手游开发|Xlua hotfix C#案例

1 Xlua调用C#方法并传递参数 lua调用C#协程,传递Action类型参数,c#中Action类型参数,可以直接用function进行替代

public void TestFuntion() { Action callBack = (res) => { Debug.Log("res is " + res); }; StartCoroutine(TextEnumerator(callBack)); }IEnumerator TextEnumerator(Action callBack) { yield return new WaitForSeconds(0.1f); Debug.Log("finish waite in unity"); callBack?.Invoke("excute callback"); }

lua hotfix重写TestFuntion方法
xlua.hotfix( CS.GameMain, { TestFuntion = function(self) local endAction = function(res) print("lua endAction", res) end self:StartCoroutine(self:TextEnumerator(endAction)) end; })

执行结果
手游开发|Xlua hotfix C#案例
文章图片

lua调用C#协程,传递集合类型参数,c#中集合类型参数,可以直接用table类型数据进行替代
public class User { public string Name { get; set; } public int Age { get; set; }public User(string name, int age) { this.Name = name; this.Age = age; } } ......public void ShowDictionary(Dictionary dic) { foreach (var VARIABLE in dic) { Debug.Log("dic info is " + VARIABLE.Key + ":" + VARIABLE.Value.Name); } }

lua调用c#方法,参数类型是 Dictionary
xlua.hotfix( CS.GameMain, { TestFuntion = function(self) local tab={} tab["dd"] = CS.User("tom", 22) tab["ff"] = CS.User("jeck", 18) --调用C#方法,参数是 self:ShowDictionary(tab) end; })

执行结果
手游开发|Xlua hotfix C#案例
文章图片

2重写协程方法
IEnumerator TextEnumerator(Action callBack) { yield return new WaitForSeconds(0.1f); Debug.Log("finish waite in unity"); callBack?.Invoke("excute callback"); }

lua重写协程方法的时候,要用的xlua提供的工具脚本util中cs_generator方法,工具位置在XLua/Resources/xlua/util.lua.txt
local util = require("xlua.util")xlua.hotfix( CS.GameMain, { TextEnumerator = function(self, endAction) return util.cs_generator(function() coroutine.yield(UnityEngine.WaitForSeconds(0.1)) print("wait 0.1 second finish") coroutine.yield(0) print("wait finish") endAction("lua excute callback ") end) end; })

【手游开发|Xlua hotfix C#案例】运行结果
手游开发|Xlua hotfix C#案例
文章图片

.
3 lua中创建C#集合类型数据对象 lua 代码
local UnityEngine = CS.UnityEngine local util = require("xlua.util")local TestDictionary = function () --创建list local List_V3 = CS.System.Collections.Generic.List(UnityEngine.Vector3) local v3List = List_V3() v3List:Add(UnityEngine.Vector3(1,1,1)) v3List:Add(UnityEngine.Vector3(2,1,1)) v3List:Add(UnityEngine.Vector3(3,1,1)) for i=0,v3List.Count-1 do print(v3List[i]) end --创建字典 key:string, value:string local Dic_String_String=CS.System.Collections.Generic.Dictionary(CS.System.String, CS.System.String) local dicString=Dic_String_String() dicString:Add("ddd", "this is dictionary test") print(dicString:get_Item("ddd"))local vect3 = UnityEngine.Vector3(1,11,111) print(vect3)--创建字典 key:string, value:Vector3 local Dic_String_V3=CS.System.Collections.Generic.Dictionary(CS.System.String, UnityEngine.Vector3) local dic3=Dic_String_V3() dic3:Add("s0",UnityEngine.Vector3.right) dic3:Add("s1",UnityEngine.Vector3.zero) -- lua中创建的字典若键不是int类型 需要使用set_Item, get_Item特殊的访问方式 print(dic3:get_Item("s0")) print("s1 is", dic3:get_Item("s1")) dic3:set_Item("s0", CS.UnityEngine.Vector3(1,11,111)) for i,v in pairs(dic3) do print("Dictionary item:",i,v) end end; xlua.hotfix( CS.GameMain, { TestFuntion = function(self) TestDictionary() end; })

unity执行结果
手游开发|Xlua hotfix C#案例
文章图片

unity中可以正常执行,但是在IL2Cpp模式下,打包安装到手机上面之后,运行会报错 for which no ahead of time (AOT) code was generated,报错的原因好像是因为没有定义调用对象类型, 导致的
LuaException: c# exception:Attempting to call method 'System.Collections.Generic.Dictionary`2[[System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[UnityEngine.Vector3, UnityEngine.CoreModule, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]]::.ctor' for which no ahead of time (AOT) code was generated.,stack:at System.Reflection.MonoCMethod.InternalInvoke (System.Object obj, System.Object[] parameters) [0x00000] in <00000000000000000000000000000000>:0 at XLua.OverloadMethodWrap.Call (System.IntPtr L) [0x00000] in <00000000000000000000000000000000>:0 at XLua.MethodWrap.Call (System.IntPtr L) [0x00000] in <00000000000000000000000000000000>:0 at XLua.StaticLuaCallbacks.FixCSFunction (System.IntPtr L) [0x00000] in <00000000000000000000000000000000>:0 stack traceback: [C]: in local 'Dic_String_V3' mylua.lua:25: in upvalue 'TestDictionary' mylua.lua:41: in function

我这边测试的时候,发现如果在C#中有创建这个类型的dictionary类型对象,lua在次调用在手机上面就不会报错了
比如c#代码这样写
public void TestFuntion() { Action callBack = (res) => { Debug.Log("res is " + res); }; StartCoroutine(TextEnumerator(callBack)); //创建 Dictionary Dictionary dic = new Dictionary(); }

4 泛型方法 c# json序列化测试
[Serializable] public class Book { public string name ; public string price; public int pageNum; public Book(string name, string price, int page) { this.name = name; this.price = price; this.pageNum = page; }} ......public void JsonTest() { Book u = new Book("Unity 入门到放弃", "$99", 10000); string json = JsonUtility.ToJson(u).ToString(); Debug.Log(json); Book bb = FromJsone(json); Debug.Log(bb.name); }public T FromJsone(string json) { T res = JsonUtility.FromJson(json); return res; }

lua调用json反序列化方法
xlua.hotfix( CS.GameMain, { JsonTest = function(self) local u = CS.Book("lua 入门到放弃", "$88", 8888) local json = CS.UnityEngine.JsonUtility.ToJson(u) print(json) --定义泛型方法 local methord = xlua.get_generic_method(CS.GameMain,"FromJsone") --定义泛型参数类型 local fromJson = methord(CS.Book) --调用泛型方法,第一个参数是调用对象,后面是方法参数 local bb = fromJson(self, json) print(bb.name) end; })

运行结果
手游开发|Xlua hotfix C#案例
文章图片

    推荐阅读