Lua调用CS

  1. using UnityEngine;
  2. using System.Collections;
  3. using System;
  4. using XLua;
  5. using System.Collections.Generic;
  6. namespace Tutorial
  7. {
  8. [LuaCallCSharp]
  9. public class BaseClass
  10. {
  11. public static void BSFunc()
  12. {
  13. Debug.Log("Driven Static Func, BSF = "+ BSF);
  14. }
  15. public static int BSF = 1;
  16. public void BMFunc()
  17. {
  18. Debug.Log("Driven Member Func, BMF = " + BMF);
  19. }
  20. public int BMF { get; set; }
  21. }
  22. public struct Param1
  23. {
  24. public int x;
  25. public string y;
  26. }
  27. [LuaCallCSharp]
  28. public enum TestEnum
  29. {
  30. E1,
  31. E2
  32. }
  33. [LuaCallCSharp]
  34. public class DrivenClass : BaseClass
  35. {
  36. [LuaCallCSharp]
  37. public enum TestEnumInner
  38. {
  39. E3,
  40. E4
  41. }
  42. public void DMFunc()
  43. {
  44. Debug.Log("Driven Member Func, DMF = " + DMF);
  45. }
  46. public int DMF { get; set; }
  47. public double ComplexFunc(Param1 p1, ref int p2, out string p3, Action luafunc, out Action csfunc)
  48. {
  49. Debug.Log("P1 = {x=" + p1.x + ",y=" + p1.y + "},p2 = "+ p2);
  50. luafunc();
  51. p2 = p2 * p1.x;
  52. p3 = "hello " + p1.y;
  53. csfunc = () =>
  54. {
  55. Debug.Log("csharp callback invoked!");
  56. };
  57. return 1.23;
  58. }
  59. public void TestFunc(int i)
  60. {
  61. Debug.Log("TestFunc(int i)");
  62. }
  63. public void TestFunc(string i)
  64. {
  65. Debug.Log("TestFunc(string i)");
  66. }
  67. public static DrivenClass operator +(DrivenClass a, DrivenClass b)
  68. {
  69. DrivenClass ret = new DrivenClass();
  70. ret.DMF = a.DMF + b.DMF;
  71. return ret;
  72. }
  73. public void DefaultValueFunc(int a = 100, string b = "cccc", string c = null)
  74. {
  75. UnityEngine.Debug.Log("DefaultValueFunc: a=" + a + ",b=" + b + ",c=" + c);
  76. }
  77. public void VariableParamsFunc(int a, params string[] strs)
  78. {
  79. UnityEngine.Debug.Log("VariableParamsFunc: a =" + a);
  80. foreach (var str in strs)
  81. {
  82. UnityEngine.Debug.Log("str:" + str);
  83. }
  84. }
  85. public TestEnum EnumTestFunc(TestEnum e)
  86. {
  87. Debug.Log("EnumTestFunc: e=" + e);
  88. return TestEnum.E2;
  89. }
  90. public Action<string> TestDelegate = (param) =>
  91. {
  92. Debug.Log("TestDelegate in c#:" + param);
  93. };
  94. public event Action TestEvent;
  95. public void CallEvent()
  96. {
  97. TestEvent();
  98. }
  99. public ulong TestLong(long n)
  100. {
  101. return (ulong)(n + 1);
  102. }
  103. class InnerCalc : Calc
  104. {
  105. public int add(int a, int b)
  106. {
  107. return a + b;
  108. }
  109. public int id = 100;
  110. }
  111. public Calc GetCalc()
  112. {
  113. return new InnerCalc();
  114. }
  115. public void GenericMethod<T>()
  116. {
  117. Debug.Log("GenericMethod<" + typeof(T) + ">");
  118. }
  119. }
  120. [LuaCallCSharp]
  121. public interface Calc
  122. {
  123. int add(int a, int b);
  124. }
  125. [LuaCallCSharp]
  126. public static class DrivenClassExtensions
  127. {
  128. public static int GetSomeData(this DrivenClass obj)
  129. {
  130. Debug.Log("GetSomeData ret = " + obj.DMF);
  131. return obj.DMF;
  132. }
  133. public static int GetSomeBaseData(this BaseClass obj)
  134. {
  135. Debug.Log("GetSomeBaseData ret = " + obj.BMF);
  136. return obj.BMF;
  137. }
  138. public static void GenericMethodOfString(this DrivenClass obj)
  139. {
  140. obj.GenericMethod<string>();
  141. }
  142. }
  143. }
  144. public class LuaCallCs : MonoBehaviour {
  145. LuaEnv luaenv = null;
  146. string script = @"
  147. function demo()
  148. --new C#对象
  149. local newGameObj = CS.UnityEngine.GameObject()
  150. local newGameObj2 = CS.UnityEngine.GameObject('helloworld')
  151. print(newGameObj, newGameObj2)
  152. --访问静态属性,方法
  153. local GameObject = CS.UnityEngine.GameObject
  154. print('UnityEngine.Time.deltaTime:', CS.UnityEngine.Time.deltaTime) --读静态属性
  155. CS.UnityEngine.Time.timeScale = 0.5 --写静态属性
  156. print('helloworld', GameObject.Find('helloworld')) --静态方法调用
  157. --访问成员属性,方法
  158. local DrivenClass = CS.Tutorial.DrivenClass
  159. local testobj = DrivenClass()
  160. testobj.DMF = 1024--设置成员属性
  161. print(testobj.DMF)--读取成员属性
  162. testobj:DMFunc()--成员方法
  163. --基类属性,方法
  164. print(DrivenClass.BSF)--读基类静态属性
  165. DrivenClass.BSF = 2048--写基类静态属性
  166. DrivenClass.BSFunc();--基类静态方法
  167. print(testobj.BMF)--读基类成员属性
  168. testobj.BMF = 4096--写基类成员属性
  169. testobj:BMFunc()--基类方法调用
  170. --复杂方法调用
  171. local ret, p2, p3, csfunc = testobj:ComplexFunc({x=3, y = 'john'}, 100, function()
  172. print('i am lua callback')
  173. end)
  174. print('ComplexFunc ret:', ret, p2, p3, csfunc)
  175. csfunc()
  176. --重载方法调用
  177. testobj:TestFunc(100)
  178. testobj:TestFunc('hello')
  179. --操作符
  180. local testobj2 = DrivenClass()
  181. testobj2.DMF = 2048
  182. print('(testobj + testobj2).DMF = ', (testobj + testobj2).DMF)
  183. --默认值
  184. testobj:DefaultValueFunc(1)
  185. testobj:DefaultValueFunc(3, 'hello', 'john')
  186. --可变参数
  187. testobj:VariableParamsFunc(5, 'hello', 'john')
  188. --Extension methods
  189. print(testobj:GetSomeData())
  190. print(testobj:GetSomeBaseData()) --访问基类的Extension methods
  191. testobj:GenericMethodOfString() --通过Extension methods实现访问泛化方法
  192. --枚举类型
  193. local e = testobj:EnumTestFunc(CS.Tutorial.TestEnum.E1)
  194. print(e, e == CS.Tutorial.TestEnum.E2)
  195. print(CS.Tutorial.TestEnum.__CastFrom(1), CS.Tutorial.TestEnum.__CastFrom('E1'))
  196. print(CS.Tutorial.DrivenClass.TestEnumInner.E3)
  197. assert(CS.Tutorial.BaseClass.TestEnumInner == nil)
  198. --Delegate
  199. testobj.TestDelegate('hello') --直接调用
  200. local function lua_delegate(str)
  201. print('TestDelegate in lua:', str)
  202. end
  203. testobj.TestDelegate = lua_delegate + testobj.TestDelegate --combine,这里演示的是C#delegate作为右值,左值也支持
  204. testobj.TestDelegate('hello')
  205. testobj.TestDelegate = testobj.TestDelegate - lua_delegate --remove
  206. testobj.TestDelegate('hello')
  207. --事件
  208. local function lua_event_callback1() print('lua_event_callback1') end
  209. local function lua_event_callback2() print('lua_event_callback2') end
  210. testobj:TestEvent('+', lua_event_callback1)
  211. testobj:CallEvent()
  212. testobj:TestEvent('+', lua_event_callback2)
  213. testobj:CallEvent()
  214. testobj:TestEvent('-', lua_event_callback1)
  215. testobj:CallEvent()
  216. testobj:TestEvent('-', lua_event_callback2)
  217. --64位支持
  218. local l = testobj:TestLong(11)
  219. print(type(l), l, l + 100, 10000 + l)
  220. --typeof
  221. newGameObj:AddComponent(typeof(CS.UnityEngine.ParticleSystem))
  222. --cast
  223. local calc = testobj:GetCalc()
  224. calc:add(1, 2)
  225. assert(calc.id == 100)
  226. cast(calc, typeof(CS.Tutorial.Calc))
  227. calc:add(1, 2)
  228. assert(calc.id == nil)
  229. end
  230. demo()
  231. --协程下使用
  232. local co = coroutine.create(function()
  233. print('------------------------------------------------------')
  234. demo()
  235. end)
  236. assert(coroutine.resume(co))
  237. ";
  238. // Use this for initialization
  239. void Start () {
  240. luaenv = new LuaEnv();
  241. luaenv.DoString(script);
  242. }
  243. // Update is called once per frame
  244. void Update () {
  245. if (luaenv != null)
  246. {
  247. luaenv.Tick();
  248. }
  249. }
  250. void OnDestroy()
  251. {
  252. luaenv.Dispose();
  253. }
  254. }