找回密码
 立即注册
查看: 361|回复: 0

Xlua hotfix C#案例

[复制链接]
发表于 2023-4-10 17:38 | 显示全部楼层 |阅读模式
1 Xlua调用C#方法并传递参数

lua调用C#协程,传递Action类型参数,c#中Action类型参数,可以直接用function进行替代
  1. public void TestFuntion()
  2.     {
  3.         Action<string> callBack = (res) =>
  4.         {
  5.             Debug.Log("res is " + res);
  6.         };
  7.         StartCoroutine(TextEnumerator(callBack));
  8.     }
  9.     IEnumerator TextEnumerator(Action<string> callBack)
  10.     {
  11.         yield return new WaitForSeconds(0.1f);
  12.         Debug.Log("finish waite in unity");
  13.         callBack?.Invoke("excute callback");
  14.     }
复制代码
lua hotfix重写TestFuntion方法
  1. xlua.hotfix( CS.GameMain, {
  2.         TestFuntion = function(self)
  3.                 local endAction = function(res)
  4.                         print("lua endAction", res)
  5.                 end
  6.                 self:StartCoroutine(self:TextEnumerator(endAction))
  7.         end;
  8. })
复制代码
执行结果



lua调用C#协程,传递集合类型参数,c#中集合类型参数,可以直接用table类型数据进行替代
  1. public class User
  2. {
  3.     public string Name { get; set; }
  4.     public int Age { get; set; }
  5.     public User(string name, int age)
  6.     {
  7.         this.Name = name;
  8.         this.Age = age;
  9.     }
  10. }
  11. ......
  12. public void ShowDictionary(Dictionary<string, User> dic)
  13.     {
  14.         foreach (var VARIABLE in dic)
  15.         {
  16.             Debug.Log("dic info is " + VARIABLE.Key + ":" + VARIABLE.Value.Name);
  17.         }
  18.     }
复制代码
lua调用c#方法,参数类型是 Dictionary<string, User>
  1. xlua.hotfix( CS.GameMain, {
  2.         TestFuntion = function(self)
  3.                 local tab={}
  4.                 tab["dd"] = CS.User("tom", 22)
  5.                 tab["ff"] = CS.User("jeck", 18)
  6.                 --调用C#方法,参数是
  7.                 self:ShowDictionary(tab)
  8.         end;
  9. })
复制代码
执行结果



2重写协程方法
  1. IEnumerator TextEnumerator(Action<string> callBack)
  2.     {
  3.         yield return new WaitForSeconds(0.1f);
  4.         Debug.Log("finish waite in unity");
  5.         callBack?.Invoke("excute callback");
  6.     }
复制代码
lua重写协程方法的时候,要用的xlua提供的工具脚本util中cs_generator方法,工具位置在XLua/Resources/xlua/util.lua.txt
  1. local util = require("xlua.util")
  2. xlua.hotfix( CS.GameMain, {
  3.        
  4.         TextEnumerator = function(self, endAction)
  5.                 return util.cs_generator(function()
  6.                         coroutine.yield(UnityEngine.WaitForSeconds(0.1))
  7.                         print("wait 0.1 second finish")
  8.                         coroutine.yield(0)
  9.                         print("wait finish")
  10.                         endAction("lua excute callback ")
  11.                 end)
  12.         end;
  13. })
复制代码
运行结果


.
3 lua中创建C#集合类型数据对象

lua 代码
  1. local UnityEngine = CS.UnityEngine
  2. local util = require("xlua.util")
  3. local TestDictionary = function (  )
  4.                 --创建list
  5.                 local List_V3 = CS.System.Collections.Generic.List(UnityEngine.Vector3)
  6.                 local v3List = List_V3()
  7.                 v3List:Add(UnityEngine.Vector3(1,1,1))
  8.                 v3List:Add(UnityEngine.Vector3(2,1,1))
  9.                 v3List:Add(UnityEngine.Vector3(3,1,1))
  10.                 for i=0,v3List.Count-1 do
  11.                                 print(v3List[i])
  12.                 end
  13.                 --创建字典 key:string, value:string
  14.                 local Dic_String_String=CS.System.Collections.Generic.Dictionary(CS.System.String, CS.System.String)
  15.                 local dicString=Dic_String_String()
  16.                 dicString:Add("ddd", "this is dictionary test")
  17.                 print(dicString:get_Item("ddd"))
  18.                 local vect3 = UnityEngine.Vector3(1,11,111)
  19.                 print(vect3)
  20.                 --创建字典 key:string, value:Vector3
  21.                 local Dic_String_V3=CS.System.Collections.Generic.Dictionary(CS.System.String, UnityEngine.Vector3)
  22.                 local dic3=Dic_String_V3()
  23.                 dic3:Add("s0",UnityEngine.Vector3.right)
  24.                 dic3:Add("s1",UnityEngine.Vector3.zero)
  25.                 -- lua中创建的字典若键不是int类型 需要使用set_Item, get_Item特殊的访问方式
  26.                 print(dic3:get_Item("s0"))
  27.                 print("s1 is", dic3:get_Item("s1"))
  28.                 dic3:set_Item("s0", CS.UnityEngine.Vector3(1,11,111))
  29.                 for i,v in pairs(dic3) do
  30.                         print("Dictionary item:",i,v)
  31.                 end
  32. end;
  33. xlua.hotfix( CS.GameMain, {
  34.        
  35.         TestFuntion = function(self)
  36.                 TestDictionary()
  37.         end;
  38. })
复制代码
unity执行结果



unity中可以正常执行,但是在IL2Cpp模式下,打包安装到手机上面之后,运行会报错 for which no ahead of time (AOT) code was generated,报错的原因好像是因为没有定义调用对象类型, 导致的
  1. 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
  2.   at XLua.OverloadMethodWrap.Call (System.IntPtr L) [0x00000] in <00000000000000000000000000000000>:0
  3.   at XLua.MethodWrap.Call (System.IntPtr L) [0x00000] in <00000000000000000000000000000000>:0
  4.   at XLua.StaticLuaCallbacks.FixCSFunction (System.IntPtr L) [0x00000] in <00000000000000000000000000000000>:0
  5. stack traceback:
  6.         [C]: in local 'Dic_String_V3'
  7.         mylua.lua:25: in upvalue 'TestDictionary'
  8.         mylua.lua:41: in function <mylua.lua:40>
复制代码
我这边测试的时候,发现如果在C#中有创建这个类型的dictionary类型对象,lua在次调用在手机上面就不会报错了
比如c#代码这样写
  1. public void TestFuntion()
  2.     {
  3.         Action<string> callBack = (res) =>
  4.         {
  5.             Debug.Log("res is " + res);
  6.         };
  7.         StartCoroutine(TextEnumerator(callBack));
  8.         //创建 Dictionary<string, Vector3>
  9.         Dictionary<string, Vector3> dic = new Dictionary<string, Vector3>();
  10.     }
复制代码
4 泛型方法

c# json序列化测试
  1. [Serializable]
  2. public class Book
  3. {
  4.     public string name ;
  5.     public string price;
  6.     public int pageNum;
  7.     public Book(string name, string price, int page)
  8.     {
  9.         this.name = name;
  10.         this.price = price;
  11.         this.pageNum = page;
  12.     }
  13. }
  14. ......
  15. public void JsonTest()
  16.     {
  17.         Book u = new Book("Unity 入门到放弃", "$99", 10000);
  18.         string json = JsonUtility.ToJson(u).ToString();
  19.         Debug.Log(json);
  20.         Book bb = FromJsone<Book>(json);
  21.         Debug.Log(bb.name);
  22.     }
  23.     public T FromJsone<T>(string json)
  24.     {
  25.        T res = JsonUtility.FromJson<T>(json);
  26.        return res;
  27.     }
复制代码
lua调用json反序列化方法
  1. xlua.hotfix( CS.GameMain, {
  2.        
  3.         JsonTest = function(self)
  4.                 local u = CS.Book("lua 入门到放弃", "$88", 8888)
  5.                 local json = CS.UnityEngine.JsonUtility.ToJson(u)
  6.                 print(json)
  7.                 --定义泛型方法
  8.                 local methord = xlua.get_generic_method(CS.GameMain,"FromJsone")
  9.                 --定义泛型参数类型
  10.                 local fromJson = methord(CS.Book)
  11.                 --调用泛型方法,第一个参数是调用对象,后面是方法参数
  12.                 local bb = fromJson(self, json)
  13.                 print(bb.name)
  14.         end;
  15. })
复制代码
运行结果

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Unity开发者联盟 ( 粤ICP备20003399号 )

GMT+8, 2024-11-23 08:33 , Processed in 0.093325 second(s), 26 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表