xlua用法 c#調用lua腳本

C# 調用 lua

腳本基本的結構

c#腳本
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using XLua;
using System;
using System.IO;

namespace XLuaTest1
{
    [CSharpCallLua]
    public class mTable{
        public string name;
        public int value;
    }

    [LuaCallCSharp]
    public class LuaTest : MonoBehaviour
    {
        // lua虛擬機,建議全局1個
        internal static LuaEnv luaEnv = new LuaEnv(); //all lua behaviour shared one luaenv only!
        // 用於處理gc
        internal static float lastGCTime = 0;
        internal const float GCInterval = 1;//1 second 
        
        private LuaTable scriptEnv;

        // lua虛擬機與unity相杜英的三個生命週期
        private Action luaStart;
        private Action luaUpdate;
        private Action luaOnDestroy;

        void Awake()
        {
            //初始化全局表
            scriptEnv = luaEnv.NewTable();
            // 爲每個腳本設置一個獨立的環境,可一定程度上防止腳本間全局變量、函數衝突
            // 初始化本地表
            LuaTable meta = luaEnv.NewTable();
            // 把lua化境交給本地表
            meta.Set("__index", luaEnv.Global);
            // 將本地表作爲元表,給全局表
            scriptEnv.SetMetaTable(meta);
            //釋放本地表
            meta.Dispose();

            //------------------------運行腳本
            luaEnv.DoString("print(888)");
            //綁定lua秀吉的生命週期
            Action luaAwake = scriptEnv.Get<Action>("awake");
            scriptEnv.Get("start", out luaStart);
            scriptEnv.Get("update", out luaUpdate);
            scriptEnv.Get("ondestroy", out luaOnDestroy);

            if (luaAwake != null)
            {
                luaAwake();
            }
        }

        // Use this for initialization
        void Start()
        {
            //虛擬機啓動後觸發
            if (luaStart != null)
            {
                luaStart();
            }
        }

        // Update is called once per frame
        void Update()
        {
            //lua腳本跟隨mono每幀執行
            if (luaUpdate != null)
            {
                luaUpdate();
            }
            //gc相關.清除Lua的未手動釋放的LuaBase對象(比如:LuaTable, LuaFunction),以及其它一些事情。
            if (Time.time - LuaTest.lastGCTime > GCInterval)
            {
                luaEnv.Tick();
                LuaTest.lastGCTime = Time.time;
            }
        }

        void OnDestroy()
        {
            // 觸發銷燬相關動作
            if (luaOnDestroy != null)
            {
                luaOnDestroy();
            }
            // 釋放lua相關內存
            luaOnDestroy = null;
            luaUpdate = null;
            luaStart = null;
            scriptEnv.Dispose();
        }
    }
}
lua腳本
-- unity腳本啓動時調用的方法
function start()
    print("lua start...")
end
-- 銷燬時調用
function ondestroy()
    print("lua destroy")
end

c# 調用lua腳本的三種方法

【直接運行代碼】

luaEnv.DoString("print(888)");

【運行Resources目錄下的lua腳本】

// 直讀 Assets/Resources下的lua腳本。比如腳本是test.lua.txt,輸入腳本名忽略擴展名txt,即test.lua。 
TextAsset luaScript = Resources.Load<TextAsset>("lua.lua") as TextAsset;
luaEnv.DoString(luaScript.text, "", scriptEnv);

【運行任意目錄下的lua腳本】

void Start(){
	//....lua虛擬機初始化等等....//
	//加載腳本loader
	luaEnv.AddLoader(LuaTxtLoader);
	//傳入腳本路徑並執行腳本
	luaEnv.DoString("require 'Resources/lua.lua.txt'");
	// 腳本loader 用於訪問任意目錄
}
private byte[] LuaTxtLoader(ref string filePath)
{
    string luaPath = Application.dataPath + "/" + filePath;
    string strLuaContent = File.ReadAllText(luaPath);
    byte[] result = System.Text.Encoding.UTF8.GetBytes(strLuaContent);
    return result;
}  

c#調用lua腳本中的變量

【調用腳本的全局變量】

【c#代碼】

// 第二種調用腳本方法 運行Resources下的腳本
TextAsset luaScript = Resources.Load<TextAsset>("lua.lua") as TextAsset;
luaEnv.DoString(luaScript.text, "", scriptEnv);
//獲取腳本中的全局變量
int mInt = scriptEnv.Get<int>("gloableInt");
Debug.Log("int from lua script:"+mInt);

【lua代碼】

-- 全局變量
gloableInt = 23

調用腳本table中的數據

【lua代碼】

-- 全局變量
mTable = {
    name = "number",
    value = 3
}
mTable1 = {"蒼井空", "小澤瑪利亞"}

【c#代碼:用類映射讀取】

//爲了調用lua table必須在c#創建相應的結構
public class mTable{
    public string name;
    public int value;
}
public class luaTest:MonoBehaviour{
	void Start(){
			// 用mTable類 映射lua腳本的同結構table
            mTable mtable = scriptEnv.Get<mTable>("mTable");
            Debug.Log("int from lua script:" + mtable.name);
	}
}

【c#代碼:用Dictionary 映射鍵值對數據】

	void Start(){
            // 用Dictionary 映射鍵值對數據
            Dictionary<string, object> dic = luaEnv.Global.Get<Dictionary<string,object>>("mTable");
            foreach (string item in dic.Keys)
            {
                print(item + " " + dic[item]);
            }
	}

【c#代碼:用list映射沒有key的table數據】

	void Start(){
            List<object> list = luaEnv.Global.Get<List<object>>("mTable1");
            foreach (var item in list)
            {
                print(item);
            }
	}

【c#代碼:用LuaTable映射沒有key的table數據】

	void Start(){
            // 使用LuaTable類映射
            LuaTable luaTable = luaEnv.Global.Get<LuaTable>("mTable");
            print(luaTable.Get<string>("name"));
	}

c# 調用lua腳本中的函數

沒有參數的全局函數

【c# 代碼】

// 用Action接受函數
Action act1 = luaEnv.Global.Get<Action>("func");
// 執行
act1();
// 用完了必須註銷,否則無法gc
act1 = null;

【lua 代碼】

function func()
    print("func");
end

帶參數和返回值的全局函數

修改帶有【CSharpCallLua】標籤的代碼後,必須生成xlua代碼,否則會發生InvalidCastException的報錯
步驟:點擊unity工具欄 > xLua > Generate Code
【c# 代碼】

// 定義委託 並添加編譯標籤
[CSharpCallLua]
public delegate int Add(int a, int b);

// 執行委託
Add add = scriptEnv.Get<Add>("add");
Debug.Log("有參的方法返回值:" + add(3, 9)); 
//用完必須註銷
add = null;

【lua 代碼】

function add(a,b)
    print('luaadd:',a+b);
    return a+b;
end

有多個返回值的全局函數(ref or out)

修改帶有【CSharpCallLua】標籤的代碼後,必須生成xlua代碼,否則會發生InvalidCastException的報錯
步驟:點擊unity工具欄 > xLua > Generate Code
【c# 代碼】

// 定義委託 並添加編譯標籤
// lua代碼中的方法有2個參數,4個返回值。在c#中聲明時都要轉成參數。包括2個普通參數,4個out/ref參數
[CSharpCallLua]
public delegate void Add(int x, int y, out int a, out int b, out string s, out int c);

// 獲取腳本中的函數
Add add = scriptEnv.Get<Add>("add");
//聲明返回變量
int a,b,c;string s;
//執行方法,輸入兩個參數,返回4個值
add(3, 9, out a, out b, out s, out c) ;
Debug.Log("有參的方法返回值:" + a + "-" + b + "-" + s + "-" + c); 
//必須註銷,否則無法gc
add = null;

【lua 代碼】

--輸入2參數,返回4參數  ,在c#的委託中都要處理成輸入參數。
function add(a,b)
    print('luaadd:',a+b);
    return 9,6,'結果:',a+b;
end
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章