使用自定義委託來呼叫Lua中的多返回值和長引數型別函式

畅知發表於2024-05-09

使用自定義lua解析管理器呼叫函式

使用自定義委託來呼叫lua指令碼中的多返回值函式和長引數型別的函式。

先看程式碼,依舊是上篇文章中所貼的指令碼。新增呼叫兩個函式testFunc

using System;
using BaseFramework;
using LuaInterface;
using UnityEngine;
using UnityEngine.Events;
using Object = System.Object;

namespace CallLua
{
    public class CallLuaEntrance:MonoBehaviour
    {
        //+ 委託
        public delegate int CustomCallFunc(int a, out int b, out int c, out string d, out bool e);
        public delegate void CustomCallParams(int a, params Object[] objects);
        private void Start()
        {
            CallLuaManager.Instance().Init();
            CallLuaManager.Instance().Require("Main");
            //獲取全域性變數
            Debug.Log(CallLuaManager.Instance().LuaState["string1"]);
            //無法獲取lua指令碼中的區域性變數
            CallLuaManager.Instance().LuaState["string1"] = "我被修改了!";
            Debug.Log(CallLuaManager.Instance().LuaState["string1"]);
            //可以理解LuaState中儲存的所有全域性變數列表
            //如果有則可以檢視並修改
            //如果沒有則新建
            CallLuaManager.Instance().LuaState["newGloString"] = "我是新來的,是Lua全域性變數";
            
            //獲取執行無參無返回值的lua函式
            LuaFunction luaFunction = CallLuaManager.Instance().LuaState.GetFunction("testFunc");
            luaFunction.Call();
            luaFunction.Dispose(); 
            
            //直接獲取
            luaFunction = CallLuaManager.Instance().LuaState["testFunc"] as LuaFunction;
            luaFunction.Call();
            luaFunction.Dispose();
            
            //存入委託中再使用
            luaFunction = CallLuaManager.Instance().LuaState.GetFunction("testFunc");
            UnityAction action = luaFunction.ToDelegate<UnityAction>();
            action();
            
            //-------------------------------------------------------------------------------------------------
            //有參有返回值函式獲取呼叫 方式1
            luaFunction = CallLuaManager.Instance().LuaState.GetFunction("testFunc1");
            luaFunction.BeginPCall();
            luaFunction.Push(66);
            luaFunction.PCall();
            int res = (int)luaFunction.CheckNumber();
            Debug.Log("引數為"+66+" ,返回值為"+res);
            luaFunction.EndPCall();
            
            //透過函式的Invoke方法來呼叫  方式2
            //<引數型別,返回值型別>
            res = luaFunction.Invoke<int, int>(88);
            Debug.Log("引數為"+88+" ,返回值為"+res);
            
            //透過委託呼叫              方式3
            Func<int, int> func = luaFunction.ToDelegate<Func<int, int>>();
            res = func(99);
            Debug.Log("引數為"+99+" ,返回值為"+res);
            
            //透過解析器直接呼叫          方式4  和2本質上是一樣的掉用方式
            res = CallLuaManager.Instance().LuaState.Invoke<int, int>("testFunc1", 166, true);
            Debug.Log("引數為"+166+" ,返回值為"+res);
            
            //+ 新增內容
            //----------------------------多返回值函式----------------------------------------------------
            //001直接獲取 執行結果 傳統方式
            luaFunction = CallLuaManager.Instance().LuaState.GetFunction("testFunc2");
            luaFunction.BeginPCall();
            luaFunction.Push(566);
            luaFunction.PCall();
            int res1 = (int)luaFunction.CheckNumber();
            int res2 = (int)luaFunction.CheckNumber();
            int res3 = (int)luaFunction.CheckNumber();
            string res4 = luaFunction.CheckString();
            bool res5 = luaFunction.CheckBoolean();
            Debug.Log("多返回值函式數值結果--->"+res1+","+res2+","+res3+","+res4+","+res5);
            
            //002使用委託方式呼叫函式
            CustomCallFunc customCallFunc = luaFunction.ToDelegate<CustomCallFunc>();
            int b2, b3;
            string s2;
            bool bl;
            //注意 res接收第一個返回值 其它都按照out 變數賦值出
            int res0 = customCallFunc(788, out b2, out b3, out s2, out bl);
            Debug.Log("多返回值函式數值結果--->"+res0+","+b2+","+b3+","+","+s2+","+bl);
            
            //--------------------------------------------長引數函式呼叫--------------------------------
            luaFunction = CallLuaManager.Instance().LuaState.GetFunction("testFunc3");
            CustomCallParams customCallParams = luaFunction.ToDelegate<CustomCallParams>();
            customCallParams(1, 2, "tony", true, 666.66);
            
            //也可以直接呼叫 call用來呼叫void 型別函式
            luaFunction.Call<int,bool,float,string>(56,false,88.88f,"Chang");
            luaFunction.Call(98,365,false,88.88f,"Chang");//不給泛型也可以!

            CallLuaManager.Instance().Dispose();
        }
    }
}

注意!在tolua中使用自定義委託時候,需要在Seting指令碼中新增自定義委託,之後再重新Generate一下。

image-20240509205251581

image-20240509205422368

要呼叫的Main.lua

--主入口函式。從這裡開始lua邏輯
function Main()					
	print("logic start")	 		
end

Main()
--場景切換通知
function OnLevelWasLoaded(level)
	collectgarbage("collect")
	Time.timeSinceLevelLoad = 0
end

--全域性變數
string1 = "我是全域性變數"

function testFunc()
	print("無參無返回值函式呼叫成功!")
end
--有引數有返回值的函式
function testFunc1(a)  
	return a + 100
end
--多返回值函式
function testFunc2(e)  
	print("多返回值函式執行")
	return e,e+100,e+200,"yes!",true
end
--變長引數函式
function testFunc3(a,...)  
	print("變長引數函式---")
	print(a)
	args = {...}
	for k,v in pairs(args) do
		print(k,v)
	end
end

function OnApplicationQuit()
	
end

好了,現在自定義的lua解析管理器已經完善對lua中全域性變數的訪問修改和新增、以及多種函式型別的呼叫。

先到這裡了,接下來要接著完善管理器的功能,敬請期待!

相關文章