自定義Lua解析器管理器-------演化指令碼V0.5

畅知發表於2024-05-08

[3]自定義Lua解析器管理器-------演化指令碼V0.5

方便我們在專案中使用Lua解析方法,我們封裝管理一個lua解析器,管理LuaState的方法執行。

解析器指令碼:

using LuaInterface;

namespace BaseFramework
{
    /// <summary>
    /// 自定義的toLua解析器
    /// </summary>
    public class CallLuaManager:SingletonAutoMono<CallLuaManager>
    {
        private LuaState _luaState;
        /// <summary>
        /// 供外部獲取使用的屬性
        /// </summary>
        public LuaState LuaState
        {
            get
            {
                return _luaState;
            }
        }

        public void Init()
        {
            _luaState = new LuaState();
            _luaState.Start();
            //初始化委託工廠
            DelegateFactory.Init();
        }

        public void Require(string fileName)
        {
            _luaState.Require(fileName);
        }

        public void Dispose()
        {
            if(_luaState==null)
                return;
            _luaState.CheckTop();
            _luaState.Dispose();
            _luaState = null;
        }
    }
}

image-20240508080302400

我們開始測試使用,其主要完成對Lua指令碼中的全域性變數的獲取並賦值,Lua指令碼中的無參無返回值函式呼叫、有參有返回值函式的四種方式呼叫,熟悉相關的API ,可以自行執行學習

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

namespace CallLua
{
    public class CallLuaEntrance:MonoBehaviour
    {
        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);
            
            CallLuaManager.Instance().Dispose();
        }
    }
}

其呼叫的lua測試指令碼------Main.lua 放置在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 OnApplicationQuit()
	
end

相關文章