参考链接:
http://blog.sina.com.cn/s/blog_6788cd880102wbc0.html
1.c#层
LuaComponent.cs
1 using LuaInterface; 2 using UnityEngine; 3 4 public class LuaComponent : MonoBehaviour 5 { 6 private LuaTable table; 7 8 private LuaFunction funcAwake; 9 private LuaFunction funcStart; 10 private LuaFunction funcUpdate; 11 12 [SerializeField] 13 private string tableName; 14 15 public static LuaTable Add(GameObject go, LuaTable tableClass) 16 { 17 LuaFunction func = tableClass.GetLuaFunction("New"); 18 if (func == null) 19 { 20 return null; 21 } 22 23 LuaComponent cmp = go.AddComponent<LuaComponent>(); 24 cmp.table = func.Invoke<LuaTable, LuaTable>(tableClass); 25 26 cmp.funcAwake = tableClass.GetLuaFunction("Awake"); 27 cmp.funcStart = tableClass.GetLuaFunction("Start"); 28 cmp.funcUpdate = tableClass.GetLuaFunction("Update"); 29 30 string name = cmp.table.GetStringField("tableName"); 31 if (name != null) 32 { 33 cmp.tableName = name; 34 } 35 36 cmp.CallAwake(); 37 38 return cmp.table; 39 } 40 41 public static LuaTable Get(GameObject go, LuaTable table) 42 { 43 LuaComponent[] cmps = go.GetComponents<LuaComponent>(); 44 for (int i = 0; i < cmps.Length; i++) 45 { 46 if (table == cmps[i].table.GetMetaTable()) 47 { 48 return cmps[i].table; 49 } 50 } 51 return null; 52 } 53 54 void CallAwake() 55 { 56 if (funcAwake != null) 57 { 58 funcAwake.Call(table, gameObject); 59 } 60 } 61 62 void Start() 63 { 64 if (funcStart != null) 65 { 66 funcStart.Call(table, gameObject); 67 } 68 } 69 70 void Update() 71 { 72 if (funcUpdate != null) 73 { 74 funcUpdate.Call(table); 75 } 76 } 77 }
在CustomSettings.cs中添加这个类,并重新生成wrap文件
2.lua层
TestLuaComponent.lua
1 --测试LuaComponent 2 3 TestLuaComponent = 4 { 5 tableName = "TestLuaComponent", 6 property1 = 100, 7 } 8 9 function TestLuaComponent:New() 10 local o = {}; 11 setmetatable(o, self); 12 self.__index = self; 13 return o; 14 end 15 16 function TestLuaComponent:Awake(go) 17 self.go = go; 18 logWarn("TestLuaComponent Awake:" .. go.name .. "_" .. self.property1); 19 end 20 21 function TestLuaComponent:Start(go) 22 logWarn("TestLuaComponent Start:" .. go.name .. "_" .. self.property1); 23 end 24 25 function TestLuaComponent:Update() 26 logWarn("TestLuaComponent Update:" .. self.go.name); 27 end
Game.lua
3.输出
4.分析(配合例子)
LuaComponent.Add:TestLuaComponent这个table作为参数传到c#时,会转化为LuaTable类,这时会获取table的New方法,即TestLuaComponent.New,然后传入参数TestLuaComponent,来创建一个TestLuaComponent的实例,赋值给LuaComponent中的table,因此,LuaComponent中的table是一个实例。创建过程可以表示为TestLuaComponent.New(TestLuaComponent),简写为TestLuaComponent:New()。其余的回调方法同理。
LuaComponent.Get:该方法传入的是一个TestLuaComponent,而LuaComponent中的table是一个实例,其metatable是TestLuaComponent,因为是引用类型,所以直接比较即可,找到则返回实例。
LuaComponent.CallAwake:funcAwake表示TestLuaComponent.Awake,LuaFunction.Call和LuaFunction.Invoke相比,前者没有返回值,后者有。通过调用TestLuaComponent.Awake(table, gameObject),就可以执行lua中对应的Awake方法。另外说明一下,因为添加了LuaComponent组件后c#中的Awake会立即被执行,会导致lua中的Awake无法执行,因此使用CallAwake手动触发,保证在Start前即可。
请发表评论