zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    一道模拟赛题
    Codechef Union on Tree
    BZOJ3435: [Wc2014]紫荆花之恋
    BZOJ3924: [Zjoi2015]幻想乡战略游戏
    BZOJ4372: 烁烁的游戏
    BZOJ3730: 震波
    BZOJ4317: Atm的树+2051+2117
    [六省联考2017]相逢是问候(扩展欧拉定理+预处理幂)
    「BJOI2018」治疗之雨(概率+高斯消元转递推)
    「BJOI2018」链上二次求和(线段树)
  • 原文地址:https://www.cnblogs.com/pmsl/p/7639967.html
Copyright © 2011-2022 走看看