Unity中使用Lua,大多情况下是通过C#来调用Lua脚本。但如果想让Lua像C#脚本那样,可以挂载到GameObject 上该如何做呢?
一下是根据网络上个大神的思路,整理的一段代码实现Lua脚本挂载到GameObject 上。
这里使用的是XLua
[LuaCallCSharp] public class LuaComponent : MonoBehaviour { public LuaTable luaTable; LuaFunction luaStart; LuaFunction luaUpdate; LuaFunction luaOnDestroy ; LuaFunction luaAwake ; LuaFunction luaOnEnable; LuaFunction luaFixedUpdate; LuaFunction luaOnDisable; LuaFunction luaLateUpdate; /// <summary> /// 添加lua组件 /// </summary> /// <param name="go"></param> /// <param name="tableClass"></param> /// <returns></returns> public static LuaTable Add(GameObject go,LuaTable tableClass) { LuaFunction luaCtor = tableClass.Get<LuaFunction>("ctor"); if ( null != luaCtor) { object[] rets = luaCtor.Call(tableClass); if (1 != rets.Length) { return null; } LuaComponent cmp = go.AddComponent<LuaComponent>(); cmp.luaTable = (LuaTable)rets[0]; cmp.initLuaFunction(); cmp.CallAwake(); return cmp.luaTable; } else { throw new Exception("Lua function .ctor not found"); } } /// <summary> /// 获取lua组件 /// </summary> /// <param name="go"></param> /// <param name="table"></param> /// <returns></returns> public static LuaTable Get(GameObject go,LuaTable table) { LuaComponent[] cmps = go.GetComponents<LuaComponent>(); string tableStr = table.ToString(); for(int i = 0; i < cmps.Length;i++) { string temp = cmps[i].luaTable.ToString(); if(string.Equals(tableStr,cmps[i].luaTable.ToString())) { return cmps[i].luaTable; } } return null; } /// <summary> /// 设置组件父节点 /// </summary> /// <param name="go"></param> /// <param name="parent"></param> public static void SetParent(GameObject go,Transform parent) { go.transform.SetParent(parent); } /// <summary> /// 初始化Lua脚本中的方法 /// </summary> void initLuaFunction() { luaOnDestroy = luaTable.Get<LuaFunction>("OnDestroy"); luaAwake = luaTable.Get<LuaFunction>("Awake"); luaStart = luaTable.Get<LuaFunction>("Start"); luaUpdate = luaTable.Get<LuaFunction>("Update"); luaOnEnable = luaTable.Get<LuaFunction>("OnEnable"); luaFixedUpdate = luaTable.Get<LuaFunction>("FixedUpdate"); luaOnDisable = luaTable.Get<LuaFunction>("OnDisable"); luaLateUpdate = luaTable.Get<LuaFunction>("LateUpdate"); } /// <summary> /// 调用lua脚本中定义的Awake方法 /// </summary> void CallAwake() { if ( null != luaAwake) { luaAwake.Call(luaTable, gameObject); } } /// <summary> /// 调用lua脚本中定义的Start方法 /// </summary> private void Start() { if ( null != luaStart) { luaStart.Call(luaTable, gameObject); } } /// <summary> /// 调用lua脚本中定义的Update方法 /// </summary> private void Update() { if (null != luaUpdate) { luaUpdate.Call(); } } /// <summary> /// 调用lua脚本中定义的FixedUpdate方法 /// </summary> private void FixedUpdate() { if (null != luaFixedUpdate) { luaFixedUpdate.Call(); } } /// <summary> /// 调用lua脚本中定义的OnDestroy方法 /// </summary> private void OnDestroy() { if (null != luaOnDestroy) { luaOnDestroy.Call(); } } /// <summary> /// 调用lua脚本中定义的 OnEnable /// </summary> private void OnEnable() { if (null != luaOnEnable) { luaOnEnable.Call(); } } /// <summary> /// 调用lua脚本中定义的 OnDisable /// </summary> private void OnDisable() { if (null != luaOnDisable) { luaOnDisable.Call(); } } /// <summary> /// 调用lua脚本中定义的 LateUpdate /// </summary> private void LateUpdate() { if (null != luaLateUpdate) { luaLateUpdate.Call(); } } }
以上LuaComponent.cs 是一个工具类,以帮助将Lua脚本挂载到一个GameObject 上。
一下是测试代码,该代码有一个C#脚本调用
require "TestCmp"
-- 将TestCmp 脚本挂载到当前GameObject上。
function addLuaScript()
local cmp1 = CS.LuaComponent.Add(self.gameObject, TestCmp)
cmp1.name = "TestCmp"
end
以下是 TestCmp.Lua
TestCmp = { name = "TestCmp" } function TestCmp:Awake(gameObject) print("GameObject "..gameObject.name)end function TestCmp:Start() print("TestCmp start...") end function TestCmp:OnEnable() print("TestCmp OnEnable...") end function TestCmp:OnDestroy() print("TestCmp OnDestroy...") end function TestCmp:OnDisable() print("TestCmp OnDisable...") end function TestCmp:ctor(obj) local o = {} setmetatable(o,self) self.__index = self return o end