Unity中将lua脚本挂载到GameObject

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