Lua调用c#

十念  金牌会员 | 2024-8-12 21:31:35 | 显示全部楼层 | 阅读模式
打印 上一主题 下一主题

主题 568|帖子 568|积分 1704

1. 类


  1. --lua中使用C#的类非常简单
  2. --固定套路
  3. --CS.命名空间.类名
  4. --Unity的类 比如 GameObject Transform等等 —— CS.UnityEngine.类名
  5. --CS.UnityEngine.GameObject
  6. --通过C#中的类 实例化一个对象 lua中没有new 所以我们直接 类名括号就是实例化对象
  7. --默认调用的 相当于就是无参构造
  8. local obj1 = CS.UnityEngine.GameObject()
  9. local obj2 = CS.UnityEngine.GameObject("ABC")
  10. --为了方便使用 并且节约性能 定义全局变量存储 C#中的类
  11. --相当于取了一个别名
  12. GameObject = CS.UnityEngine.GameObject
  13. local obj3 = GameObject("ABC好爱同学们")
  14. --类中的静态对象 可以直接使用.来调用
  15. local obj4 = GameObject.Find("ABC")
  16. --得到对象中的成员变量  直接对象 . 即可
  17. print(obj4.transform.position)
  18. Debug = CS.UnityEngine.Debug
  19. Debug.Log(obj4.transform.position)
  20. Vector3 = CS.UnityEngine.Vector3
  21. --如果使用对象中的 成员方法!!!!一定要加:
  22. obj4.transform:Translate(Vector3.right)
  23. Debug.Log(obj4.transform.position)
  24. --自定义类 使用方法 相同  只是命名空间不同而已
  25. local t = CS.Test()
  26. t:Speak("test说话")
  27. local t2 = CS.MrTang.Test2()
  28. t2:Speak("test2说话")
  29. --继承了Mono的类
  30. --继承了Mono的类 是不能直接new
  31. local obj5 = GameObject("加脚本测试")
  32. --通过GameObject的 AddComponent添加脚本
  33. --xlua提供了一个重要方法 typeof 可以得到类的Type
  34. --xlua中不支持 无参泛型函数  所以 我们要使用另一个重载
  35. obj5:AddComponent(typeof(CS.LuaCallCSharp))
复制代码

  1. --枚举调用
  2. --调用Unity当中的枚举
  3. --枚举的调用规则 和 类的调用规则是一样的
  4. --CS.命名空间.枚举名.枚举成员
  5. --也支持取别名
  6. --同样 如果报错 需要在CustomSetting中去加上
  7. PrimitiveType = CS.UnityEngine.PrimitiveType
  8. GameObject = CS.UnityEngine.GameObject
  9. local obj = GameObject.CreatePrimitive(PrimitiveType.Cube)
  10. --自定义枚举 使用方法一样 只是注意命名空间即可
  11. E_MyEnum =  CS.E_MyEnum
  12. local c = E_MyEnum.Idle
  13. print(c)
  14. --枚举转换相关
  15. --数值转枚举
  16. local a = E_MyEnum.__CastFrom(1)
  17. print(a)
  18. --字符串转枚举
  19. local b = E_MyEnum.__CastFrom("Atk")
  20. print(b)
复制代码

  1. local obj = CS.Lesson3()
  2. --Lua使用C#数组相关知识
  3. --长度 userdata
  4. --C#怎么用 lua就怎么用 不能使用#去获取长度
  5. print(obj.array.Length)
  6. --访问元素
  7. print(obj.array[0])
  8. --遍历要注意 虽然lua中索引从1开始
  9. --但是数组是C#那边的规则 所以 还是得按C#的来
  10. --注意最大值 一定要减1
  11. for i=0,obj.array.Length-1 do
  12.         print(obj.array[i])
  13. end
  14. --Lua中创建一个C#的数组 Lua中表示数组和List可以用表
  15. --但是我要使用C#中???
  16. --创建C#中的数组 使用 Array类中的静态方法即可
  17. local array2 = CS.System.Array.CreateInstance(typeof(CS.System.Int32), 10)
  18. print(array2.Length)
  19. print(array2[0])
  20. print(array2[1])
  21. print(array2)
  22. print("*********Lua调用C# list相关知识点***********")
  23. --调用成员方法 用冒号!!!!!!
  24. obj.list:Add(1)
  25. obj.list:Add(2)
  26. obj.list:Add(3)
  27. --长度
  28. print(obj.list.Count)
  29. --遍历
  30. for i=0,obj.list.Count - 1 do
  31.         print(obj.list[i])
  32. end
  33. print(obj.list)
  34. --在Lua中创建一个List对象
  35. --老版本
  36. local list2 = CS.System.Collections.Generic["List`1[System.String]"]()
  37. print(list2)
  38. list2:Add("123")
  39. print(list2[0])
  40. --新版本 >v2.1.12
  41. --相当于得到了一个 List<string> 的一个类别名 需要再实例化
  42. local List_String = CS.System.Collections.Generic.List(CS.System.String)
  43. local list3 = List_String()
  44. list3:Add("5555555")
  45. print(list3[0])
  46. print("*********Lua调用C# dictionary相关知识点***********")
  47. --使用和C#一致
  48. obj.dic:Add(1, "123")
  49. print(obj.dic[1])
  50. --遍历
  51. for k,v in pairs(obj.dic) do
  52.         print(k,v)
  53. end
  54. --在Lua中创建一个字典对象
  55. --相当于得到了一个 Dictionary<string, Vector3> 的一个类别名 需要再实例化
  56. local Dic_String_Vector3 = CS.System.Collections.Generic.Dictionary(CS.System.String, CS.UnityEngine.Vector3)
  57. local dic2 = Dic_String_Vector3()
  58. dic2:Add("123", CS.UnityEngine.Vector3.right)
  59. for i,v in pairs(dic2) do
  60.         print(i,v)
  61. end
  62. --在Lua中创建的字典 直接通过键中括号得 得不到 是nil
  63. print(dic2["123"])
  64. print(dic2:TryGetValue("123"))
  65. --如果要通过键获取值 要通过这个固定方法
  66. print(dic2:get_Item("123"))
  67. dic2:set_Item("123", nil)
  68. print(dic2:get_Item("123"))
  69. local Dic_String_String = CS.System.Collections.Generic.Dictionary(CS.System.String, CS.System.String)
  70. local dic2 = Dic_String_String()
  71. dic2:Add("id_1", "hello")
  72. print(dic2:get_Item("id_1"))
  73. for key, value in pairs(dic2) do
  74.     print(key, value)
  75. end
复制代码

  1. //想要在Lua中使用拓展方法 一定要在工具类前面加上特定
  2. //建议 Lua中要使用的类 都加上该特性 可以提升性能
  3. //如果不加该特性 除了拓展方法对应的类 其它类的使用 都不会报错
  4. //但是lua是通过反射的机制去调用的C#类  效率较低
  5. [LuaCallCSharp]
  6. public static class Tools
  7. {
  8.     //Lesson4的拓展方法
  9.     public static void Move(this Lesson4 obj)
  10.     {
  11.         Debug.Log(obj.name + "移动");
  12.     }
  13. }
  14. public class Lesson4
  15. {
  16.     public string name = "EFT";
  17.     public void Speak(string str)
  18.     {
  19.         Debug.Log(str);
  20.     }
  21.     public static void Eat()
  22.     {
  23.         Debug.Log("吃东西");
  24.     }
  25. }
复制代码
  1. Lesson4 = CS.Lesson4
  2. --使用静态方法
  3. --CS.命名空间.类名.静态方法名()
  4. Lesson4.Eat()
  5. --成员方法 实例化出来用
  6. local obj = Lesson4()
  7. --成员方法 一定用冒号
  8. obj:Speak("CCC哈哈哈哈哈")
  9. --使用拓展方法 和使用成员方法 一致
  10. --要调用 C#中某个类的拓展方法 那一定要在拓展方法的静态类前面加上LuaCallCSharp特性
  11. obj:Move()
复制代码

  1. Lesson5 = CS.Lesson5
  2. local obj = Lesson5()
  3. --ref参数 会以多返回值的形式返回给lua
  4. --如果函数存在返回值 那么第一个值 就是该返回值
  5. --之后的返回值 就是ref的结果 从左到右一一对应
  6. --ref参数 需要传入一个默认值 占位置
  7. --a 相当于 函数返回值
  8. --b 第一个ref
  9. --c 第二个ref
  10. local a,b,c = obj:RefFun(1, 0, 0, 1)
  11. print(a)
  12. print(b)
  13. print(c)
  14. print("*********Lua调用C# out方法相关知识点***********")
  15. --out参数 会以多返回值的形式返回给lua
  16. --如果函数存在返回值 那么第一个值 就是该返回值
  17. --之后的返回值 就是out的结果 从左到右一一对应
  18. --out参数 不需要传占位置的值
  19. local a,b,c = obj:OutFun(20,30)
  20. print(a)
  21. print(b)
  22. print(c)
  23. --混合使用时  综合上面的规则
  24. --ref需占位 out不用传
  25. --第一个是函数的返回值  之后 从左到右依次对应ref或者out
  26. local a,b,c = obj:RefOutFun(20,1)
  27. print(a)--300
  28. print(b)--200
  29. print(c)--400
复制代码

  1. local obj = CS.Lesson6()
  2. --虽然Lua自己不支持写重载函数
  3. --但是Lua支持调用C#中的重载函数  
  4. print(obj:Calc())
  5. print(obj:Calc(15, 1))
  6. --Lua虽然支持调用C#重载函数
  7. --但是因为Lua中的数值类型 只有Number
  8. --对C#中多精度的重载函数支持不好 傻傻分不清
  9. --在使用时 可能出现意想不到的问题
  10. print(obj:Calc(10))
  11. print(obj:Calc(10.2))
  12. --解决重载函数含糊的问题
  13. --xlua提供了解决方案 反射机制
  14. --这种方法只做了解 尽量别用
  15. --Type是反射的关键类
  16. --得到指定函数的相关信息
  17. local m1 = typeof(CS.Lesson6):GetMethod("Calc", {typeof(CS.System.Int32)})
  18. local m2 = typeof(CS.Lesson6):GetMethod("Calc", {typeof(CS.System.Single)})
  19. --通过xlua提供的一个方法 把它转成lua函数来使用
  20. --一般我们转一次 然后重复使用
  21. local f1 = xlua.tofunction(m1)
  22. local f2 = xlua.tofunction(m2)
  23. --成员方法 第一个参数传对象
  24. --静态方法 不用传对象
  25. print(f1(obj, 10))
  26. print(f2(obj, 10.2))
复制代码

  1. local obj = CS.Lesson7()
  2. --委托是用来装函数的
  3. --使用C#中的委托 就是用来装lua函数的
  4. local fun = function( )
  5.         print("Lua函数Fun")
  6. end
  7. --Lua中没有复合运算符 不能+=
  8. --如果第一次往委托中加函数 因为是nil 不能直接+
  9. --所以第一次 要先等=
  10. print("*********开始加函数***********")
  11. obj.del = fun
  12. --obj.del = obj.del + fun
  13. obj.del = obj.del + fun
  14. --不建议这样写 最好最好还是 先声明函数再加
  15. obj.del = obj.del + function( )
  16.         print("临时申明的函数")
  17. end
  18. --委托执行
  19. obj.del()
  20. print("*********开始减函数***********")
  21. obj.del = obj.del - fun
  22. obj.del = obj.del - fun
  23. --委托执行
  24. obj.del()
  25. print("*********清空***********")
  26. --清空所有存储的函数
  27. obj.del = nil
  28. --清空过后得先等
  29. obj.del = fun
  30. --调用
  31. obj.del()
  32. print("*********Lua调用C# 事件相关知识点***********")
  33. local fun2 = function()
  34.         print("事件加的函数")
  35. end
  36. print("*********事件加函数***********")
  37. --事件加减函数  和 委托非常不一样
  38. --lua中使用C#事件 加函数
  39. --有点类似使用成员方 冒号事件名("+", 函数变量)
  40. obj:eventAction("+", fun2)
  41. --最好最好不要这样写
  42. obj:eventAction("+", function()
  43.         print("事件加的匿名函数")
  44. end)
  45. obj:DoEvent()
  46. print("*********事件减函数***********")
  47. obj:eventAction("-", fun2)
  48. obj:DoEvent()
  49. print("*********事件清楚***********")
  50. --清事件 不能直接设空
  51. obj:ClaerEvent()
  52. obj:DoEvent()
复制代码
  1. #region 委托和事件
  2. public class Lesson7
  3. {
  4.     //申明委托和事件
  5.     public UnityAction del;
  6.     public event UnityAction eventAction;
  7.     public void DoEvent()
  8.     {
  9.         if (eventAction != null)
  10.             eventAction();
  11.     }
  12.     public void ClaerEvent()
  13.     {
  14.         eventAction = null;
  15.     }
  16. }
  17. #endregion
复制代码

  1. local obj = CS.Lesson8()
  2. --获取长度
  3. print("行:" .. obj.array:GetLength(0))
  4. print("列:" .. obj.array:GetLength(1))
  5. --获取元素
  6. --不能通过[0,0]或者[0][0]访问元素 会报错
  7. print(obj.array:GetValue(0,0))
  8. print(obj.array:GetValue(1,0))
  9. print("********************")
  10. for i=0,obj.array:GetLength(0)-1 do
  11.         for j=0,obj.array:GetLength(1)-1 do
  12.                 print(obj.array:GetValue(i,j))
  13.         end
  14. end
  15. obj:SetValue(obj.array, 99, 0, 0)
  16. print(obj.array:GetValue(0,0))
  17. local m = typeof(CS.System.Array):GetMethod("SetValue", {typeof(CS.System.Int32), typeof(CS.System.Int32), typeof(CS.System.Int32)})
  18. print(m);
  19. local ff = xlua.tofunction(m)
  20. print(ff);
  21. ff(obj.array, 1,0,0)
  22. --print(obj.array:GetValue(0,0))
复制代码

  1. --往场景对象上添加一个脚本 如果存在就不加 如果不存在再加
  2. GameObject = CS.UnityEngine.GameObject
  3. Debug = CS.UnityEngine.Debug
  4. Rigidbody = CS.UnityEngine.Rigidbody
  5. Image = CS.UnityEngine.UI.Image
  6. local obj = GameObject("测试加脚本")
  7. --得到身上的刚体组件  如果没有 就加 有就不管
  8. local rig = obj:GetComponent(typeof(Rigidbody))
  9. print(rig)
  10. Debug.Log(rig)
  11. if rig == nil then
  12.         print(true)
  13. end
  14. local img = obj:GetComponent(typeof(Image))
  15. print(img)
  16. Debug.Log(img)
  17. --判断空
  18. --nil和null 没法进行==比较
  19. --第一种方法
  20. --if rig:Equals(nil) then
  21. --if IsNull(rig) then
  22. if rig:IsNull() then
  23.         print("123")
  24.         rig = obj:AddComponent(typeof(Rigidbody))
  25. end
  26. print(rig)
复制代码





  1. print("*********Lua调用C# 协程相关知识点***********")
  2. --xlua提供的一个工具表
  3. --一定是要通过require调用之后 才能用
  4. util = require("xlua.util")
  5. --C#中协程启动都是通过继承了Mono的类 通过里面的启动函数StartCoroutine
  6. GameObject = CS.UnityEngine.GameObject
  7. WaitForSeconds = CS.UnityEngine.WaitForSeconds
  8. --在场景中新建一个空物体  然后挂一个脚本上去 脚本继承mono使用它来开启协程
  9. local obj = GameObject("Coroutine")
  10. local mono = obj:AddComponent(typeof(CS.LuaCallCSharp))
  11. --希望用来被开启的协程函数
  12. fun = function()
  13.         local a = 1
  14.         while true do
  15.                 --lua中 不能直接使用 C#中的 yield return
  16.                 --就使用lua中的协程返回
  17.                 coroutine.yield(WaitForSeconds(1))
  18.                 print(a)
  19.                 a = a + 1
  20.                 if a > 10 then
  21.                         --停止协程和C#当中一样
  22.                         mono:StopCoroutine(b)
  23.                 end
  24.         end
  25. end
  26. --我们不能直接将 lua函数传入到开启协程中!!!!!
  27. --如果要把lua函数当做协程函数传入
  28. --必须 先调用 xlua.util中的cs_generator(lua函数)
  29. b = mono:StartCoroutine(util.cs_generator(fun))
复制代码


  1. local obj = CS.Lesson12()
  2. local child = CS.Lesson12.TestChild()
  3. local father = CS.Lesson12.TestFather()
  4. --支持有约束有参数的泛型函数
  5. obj:TestFun1(child, father)
  6. obj:TestFun1(father, child)
  7. --lua中不支持 没有约束的泛型函数
  8. --obj:TestFun2(child)
  9. --lua中不支持 有约束 但是没有参数的泛型函数
  10. --obj:TestFun3()
  11. --lua中不支持 非class的约束
  12. --obj:TestFun4(child)
  13. --有一定的使用限制
  14. --Mono打包 这种方式支持使用
  15. --il2cpp打包  如果泛型参数是引用类型才可以使用
  16. --il2cpp打包  如果泛型参数是值类型,除非C#那边已经调用过了 同类型的泛型参数 lua中才能够被使用
  17. --补充知识 让上面 不支持使用的泛型函数 变得能用
  18. --得到通用函数  
  19. --设置泛型类型再使用
  20. --xlua.get_generic_method(类, "函数名")
  21. local testFun2 = xlua.get_generic_method(CS.Lesson12, "TestFun2")
  22. local testFun2_R = testFun2(CS.System.Int32)
  23. --调用
  24. --成员方法  第一个参数 传调用函数的对象
  25. --静态方法 不用传
  26. testFun2_R(obj, 1)
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

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

x
回复

使用道具 举报

0 个回复

正序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

十念

金牌会员
这个人很懒什么都没写!

标签云

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