XLua 入门之 Lua 访问 C#

Posted Unity程序猿的学习日常

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了XLua 入门之 Lua 访问 C#相关的知识,希望对你有一定的参考价值。

构造 C# 对象


在 C# 中往往通过 new 来创建对象,而在 Lua 中是没有 new 关键字的,Lua 更多的是通过 CS 来访问 C# 相关代码的。


普通的 C# new 对象可以这样:


GameObject go = new GameObject();GameObject go2 = new GameObject('对象名称');


在 Lua 中就可以通过 CS 创建对象:


local go = CS.UnityEngine.GameObject()local go2 = CS.UnityEngine.GameObject('hehe')


当然这里创建对象只是针对 Unity 引擎中的类,也就是 CS 后接上的是 Unity 中对象类所在命名空间以及类的名字来访问,那么在我们自己自定义的类该如何访问呢?其实也是差不多的:


// C# 代码public class MyTest{ public MyTest(){} public MyTest(string str){ Debug.Log(str);  }}
// lua 代码 如果 MyTest 是内部类的话就这样访问 CS.Test.MyTest() Test 类中有 MyTest 类local myTest = CS.MyTest()local myTest2 = CS.MyTest('hello')


访问 C# 对象中的属性和方法


首先在我们自定义的 MyTest 中添加属性和方法:


    // C# 代码public class MyTest    //新增属性变量 public string name = "hehe"; public static int count = 100; public int num = 10; //新增方法 public int Add(int x, int y) { return x + y; }
public static int Mul(int a, int b) { return a / b;           }}


再来看 Lua 代码访问其属性方法以及修改:


local myTest = CS.MyTest()-- 读取成员变量print(myTest.name)-- 读取静态成员变量print(CS.MyTest.count)-- 修改成员变量myTest.name = 'name 值修改了'print(myTest.name)-- 修改静态成员变量CS.MyTest.count = 121print(CS.MyTest.count)-- 调用成员方法 调用成员方法使用冒号语法糖print(myTest:Add(1,3))-- 调用静态方法print(CS.MyTest.Mul(4,2))


访问 C# 对象中基类的属性和方法


// C# 代码public class MyTest : MyTestParent{ //类中属性方法就省略了... }
// MyTest 基类public class MyTestParent{ public int numParent = 12; public static string strParent = "strContent";
public int AddParent(int x, int y) { return x + y; }
public static int MulParent(int a, int b) { return a / b; }}
// Lua 代码 修改基类属性变量也差不多的写法print(myTest.numParent)print(CS.MyTest.strParent)print(myTest:AddParent(100,100))print(CS.MyTest.MulParent(3,3))


Lua 调用C# 中可变参数的方法


// C# 代码public class MyTest{ //可变参数的方法,传入一个 int 数组 public void Func(int x, params int[] array){ int sum = x; for (int i = 0; i < array.Length; i++) { sum += array[i]; } Debug.Log("sum = "+sum);  }}
// Lua 代码local myTest = CS.MyTest()myTest:Func(1,2,3,4,5,6,7,8,9,10) --直接在后面传入相对应的类型参数就可以了


Lua 调用C# 中复杂函数的输入输出


在 C# 的函数方法中充斥着各种输入和输出,在Lua 中也需要对这些函数进行处理:


// C# 代码public class MyTest{ //复杂函数方法 多种输入和输出 public double ComplexFunc(float p1, ref int p2, out string p3, Action luafunc, out Action csfunc) { p2 = 1 + 1; p3 = p2 * 2 + "";
luafunc();
csfunc = () => { Debug.Log("1+1=2"); }; return 0; }}
// Lua 代码local myTest = CS.MyTest()local res,p2,p3,csfunc = myTest:ComplexFunc(1,1,function()print('hello world')end)
print(res)print(p2)print(p3)csfunc()


Lua 调用复杂函数方法的规则是:C# 中普通参数算一个输入参数,ref 修饰的也是一个输入参数,从左往右一一对应;C# 中函数的返回值算一个返回值,out 算一个返回值,ref 也算一个返回值,然后从左往右依次对应。


Lua 调用C# 对象的扩展方法


// C# 代码public class MyTest{ //类中属性方法就省略了...}// MyTest类的扩展类 这里需要用到 [LuaCallCSharp] 标签 暂时不需要构建代码[LuaCallCSharp]public static class MyTestExtension{ public static void ExtFunc(this MyTest mt) { Debug.Log("这是 MyTest 扩展方法"); }}
// Lua 代码local myTest = CS.MyTest()myTest:ExtFunc()


Lua 调用C# 对象的泛型方法


// C# 代码public class MyTest{ //定义的泛型方法 public void FuncT<T>() { Debug.Log("这是泛型方法 "+typeof(T)); }}// MyTest类的扩展类 这里需要用到 [LuaCallCSharp] 标签 暂时不需要构建代码[LuaCallCSharp]public static class MyTestExtension{ public static void ExtFuncT(this MyTest mt) { Debug.Log("Lua 只能在扩展方法中调用 泛型方法"); mt.FuncT<int>(); }}
// Lua 代码local myTest = CS.MyTest()myTest:ExtFuncT()


Lua 调用C# 对象的枚举类型


// C# 代码public class MyTest{ public enum EnumType { test1, test2, test3 }
public void TestEnum(EnumType types){ Debug.Log(types); }}
// Lua 代码local myTest = CS.MyTest()-- C# 中的枚举值访问 在 Lua 中跟访问静态变量是一样的myTest:TestEnum(CS.MyTest.EnumType.test1)-- 在 MyTest 还可以使用 __CastFrom ,可以将转换整数和字符串(不用打标签 构建代码好像也可以使用 __CastFrom)myTest:TestEnum(CS.MyTest.EnumType.__CastFrom(1))
myTest:TestEnum(CS.MyTest.EnumType.__CastFrom('test1'))


Lua 调用C# 对象的委托 Delegate


// C# 代码public class MyTest{ //定义 委托且默认指定委托执行的内容 public Action<string> TestDelegate = (param) => { Debug.Log("TestDelegate in c#:" + param); };}
// Lua 代码local myTest = CS.MyTest()myTest.TestDelegate('ttt') -- 在 Lua 中直接调用 冒号都不用
-- 定义 Lua 中的 函数 function luaFuncDelegate(str) print('lua delegate' .. str)end
-- 在 Lua 中运用 + - 运算符来给 C# 中的委托添加和移除执行函数myTest.TestDelegate = myTest.TestDelegate + luaFuncDelegatemyTest.TestDelegate('gaga')myTest.TestDelegate = myTest.TestDelegate - luaFuncDelegatemyTest.TestDelegate('hehe')


Lua 调用C# 对象的 Event


// C# 代码public class MyTest{ public event Action TestEvent; public void CallEvent() { if(TestEvent != null){ Debug.Log("CallEvent C#"); TestEvent(); } }}
// Lua 代码local myTest = CS.MyTest()-- 定义 Lua 回调函数function luaEventCallBack() print('lua event callback')end-- 这里不能直接调用 event 了,还是得需要 冒号语法糖myTest:CallEvent()-- 运用 + - 运算符 给C# 中的 Event 添加移除回调函数myTest:TestEvent('+',luaEventCallBack)myTest:CallEvent()myTest:TestEvent('-',luaEventCallBack)myTest:CallEvent()


C# 复杂类型和 table 的自动转换


这里的自动转换其实跟之前的 C# 调用 Lua 差不多:


// C# 代码public struct A{ public int a;}
public struct B{ public A b; public double c;}
public class MyTest{ public void Foo(B b){} }
// Lua 代码local myTest = CS.MyTest()myTest:Foo({b = {a = 100}, c = 200})

以上是关于XLua 入门之 Lua 访问 C#的主要内容,如果未能解决你的问题,请参考以下文章

XLua 入门之 C# 访问 Lua

深入xLua实现原理之C#如何调用Lua

XLua系列讲解_XLua调用C#

lua热更框架之XLua

[Unity XLua]热更新XLua入门-俄罗斯方块实例篇

[xlua]探索笔记之协程