ToLua热更新之LuaFramework框架之Lua组件(四)
1、设计思想
在需要添加Lua组件的游戏物体上添加一个LuaComponent组件,LuaComponent引用一个lua表,这个lua表包含lua组件的各种属性以及Awake、Start等函数,由LuaComponent适时调用Lua表所包含的函数。下面列举lua组件的文件格式,它包含一个表(如Component),这个表包含property1 、property2 等属性,包含Awake、Start等方法。表中必须包含用于派生对象的New方法,它会创建一个继承自Component的表o,供LuaComponent调用。
Component= --组件表 { property1 = 100, property2 = “helloWorld” } function Component:Awake() print("TankCmp Awake name = "..self.name ); end function Component:Start() print("TankCmp Start name = "..self.name ); End --更多方法略 function Component:New(obj) local o = {} setmetatable(o, self) self.__index = self return o end
2、LuaComponent组件
LuaComponent主要有Get和Add两个静态方法,其中Get相当于UnityEngine中的GetComponent方法,Add相当于AddComponent方法,只不过这里添加的是lua组件不是c#组件。每个LuaComponent拥有一个LuaTable(lua表)类型的变量table,它既引用上述的Component表。Add方法使用AddComponent添加LuaComponent,调用参数中lua表的New方法,将其返回的表赋予table。Get方法使用GetComponents获取游戏对象上的所有LuaComponent(一个游戏对象可能包含多个lua组件,由参数table决定需要获取哪一个),通过元表地址找到对应的LuaComponent,返回lua表。代码如下:
using UnityEngine; using System.Collections; using LuaInterface; using LuaFramework; public class LuaComponent : MonoBehaviour { //Lua表 public LuaTable table; //添加LUA组件 public static LuaTable Add(GameObject go, LuaTable tableClass) { LuaFunction fun = tableClass.GetLuaFunction("New"); if (fun == null) return null; object[] rets = fun.Call (tableClass); if (rets.Length != 1) return null; LuaComponent cmp = go.AddComponent<LuaComponent>(); cmp.table = (LuaTable)rets[0]; cmp.CallAwake (); return cmp.table; } //获取lua组件 public static LuaTable Get(GameObject go,LuaTable table) { LuaComponent[] cmps = go.GetComponents<LuaComponent>(); foreach (LuaComponent cmp in cmps) { string mat1 = table.ToString(); string mat2 = cmp.table.GetMetaTable().ToString(); if(mat1 == mat2) { return cmp.table; } } return null; } //删除LUA组件的方法略,调用Destory()即可 void CallAwake () { LuaFunction fun = table.GetLuaFunction("Awake"); if (fun != null) fun.Call (table, gameObject); } void Start () { LuaFunction fun = table.GetLuaFunction("Start"); if (fun != null) fun.Call (table, gameObject); } void Update () { //效率问题有待测试和优化 //可在lua中调用UpdateBeat替代 LuaFunction fun = table.GetLuaFunction("Update"); if (fun != null) fun.Call (table, gameObject); } void OnCollisionEnter(Collision collisionInfo) { //略 } //更多函数略 }
3、调试LuaCompomemt
现在编写名为TankCmp的lua组件,测试LuaCompomemt的功能,TankCmp会在Awake、Start和Update打印出属性name。TankCmp.lua的代码如下:
TankCmp = { --里面可以放一些属性 Hp = 100, att = 50, name = "good tank", } function TankCmp:Awake() print("TankCmp Awake name = "..self.name ); end function TankCmp:Start() print("TankCmp Start name = "..self.name ); end function TankCmp:Update() print("TankCmp Update name = "..self.name ); end --创建对象 function TankCmp:New(obj) local o = {} setmetatable(o, self) self.__index = self return o end
编写Main.lua,给游戏对象添加lua组件。
require "TankCmp" --主入口函数。从这里开始lua逻辑 function Main() --组件1 local go = UnityEngine.GameObject ('go') local tankCmp1 = LuaComponent.Add(go,TankCmp) tankCmp1.name = "Tank1" --组件2 local go2 = UnityEngine.GameObject ('go2') LuaComponent.Add(go2,TankCmp) local tankCmp2 = LuaComponent.Get(go2,TankCmp) tankCmp2.name = "Tank2" end
运行游戏,即可看到lua组件的运行结果:
图:程序运行结果
图:程序运行结果
4、坦克组件
下面代码演示用lua组件实现“用键盘控制坦克移动”的功能,TankCmp.lua的代码如下:
TankCmp = { name = "good tank", } function TankCmp:Update(gameObject) print("TankCmp Update name = "..self.name ); local Input = UnityEngine.Input; local horizontal = Input.GetAxis("Horizontal"); local verticla = Input.GetAxis("Vertical"); local x = gameObject.transform.position.x + horizontal local z = gameObject.transform.position.z + verticla gameObject.transform.position = Vector3.New(x,0,z) end --创建对象 function TankCmp:New(obj) local o = {} setmetatable(o, self) self.__index = self return o end
Main.lua先加载坦克模型,然后给他添加lua组件,代码如下:
require "TankCmp" --主入口函数。从这里开始lua逻辑 function Main() LuaHelper = LuaFramework.LuaHelper; resMgr = LuaHelper.GetResManager(); resMgr:LoadPrefab('tank', { 'TankPrefab' }, OnLoadFinish); end --加载完成后的回调-- function OnLoadFinish(objs) go = UnityEngine.GameObject.Instantiate(objs[0]); LuaComponent.Add(go,TankCmp) end
运行游戏,即可用键盘的控制坦克移动。
图:坦克组件运行结果
阅读更多- ToLua热更新之LuaFramework框架之UI(五)
- ToLua热更新之LuaFramework框架之网络(六)
- ToLua热更新之LuaFramework框架之PureMVC(七)
- ToLua热更新之LuaFramework框架之声音管理器(八)
- ToLua热更新之LuaFramework框架之线程管理器(九)
- ToLua热更新之LuaFramework框架之示例程序(十)
- ToLua LuaFramework 使用实战[2]-资源热更新
- [Unity热更新]tolua# & LuaFramework(六):网络通信
- [Unity热更新]tolua# & LuaFramework(七):lua使用DOTween
- [Unity热更新]tolua# & LuaFramework(一):基础
- ToLua LuaFramework 使用实战[1]-代码热更新
- [Unity热更新]tolua# & LuaFramework(五):.proto转换为.lua
- [Unity热更新]tolua# & LuaFramework(三):lua使用list与事件委托
- [Unity热更新]tolua# & LuaFramework(十四):更新下载(中)
- [Unity热更新]tolua# & LuaFramework(十一):实践
- [Unity热更新]tolua# & LuaFramework(二):打包工具
- [Unity热更新]tolua# & LuaFramework(十):扩展工具包
- 4.Unity3D热更新-LuaFramework-Lua组件
- [Unity热更新]tolua# & LuaFramework(十三):导出apk
- [Unity热更新]tolua# & LuaFramework(九):网络通信实例