本文共 5472 字,大约阅读时间需要 18 分钟。
01.操作符重载和函数重载
C#中定义的操作符重载和函数重载在Lua中基本上能够使用,不过需要注意的是由于Lua中表示数值的类型只有一种(number),所以C#中对于数值类型之间的重载是不能够正确的识别的,通常只会调用类型符合的重载函数列表中先定义的函数[LuaCallCSharp]public class Overload{ public int Add(int num1, int num2) { Debug.Log("Add-int"); return num1 + num2; } public float Add(float num1, float num2) { Debug.Log("Add-float"); return num1 + num2; } public string Add(string num1, string num2) { Debug.Log("Add-string"); return num1 + num2; }}
local Overload=CS.Overload--获取一个类的映射local overload=CS.Overload()--实例化一个类print(overload:Add(1,2));print(overload:Add(1.5,2.1));print(overload:Add("22","22"));由于在Lua中只有一种数值类型(number),所以参数为int和float类型的Add函数都满足要求,这个时候会调用先定义的重载函数,也就是重载为int类型的Add 当先定义参数float类型后定义int类型的Add函数时,Lua代码调用就是参数类型为float的Add函数了
02.可变参数与默认参数
在Lua中调用它们的时候,参数的规则与C#中相同 对于C#的如下方法: void VariableParamsFunc(int a, params string[] strs) 可以在lua里头这样调用: testobj:VariableParamsFunc(5, ‘hello’, ‘john’)public void DefaultParam(int arg0, string arg1 = "1", int arg2 = 2) { Debug.Log("arg0:" + arg0); Debug.Log("arg1:" + arg1); Debug.Log("arg2:" + arg2); } public void VariableParam(int arg0, params string[] args) { Debug.Log("arg0:" + arg0); Debug.Log(args.Length); foreach (string arg in args) { Debug.Log(arg + " "); } }
local Overload=CS.Overload--获取一个类的映射local overload=CS.Overload()--实例化一个类overload:VariableParam(10,"1", "2", "3", "4");overload:DefaultParam(1);03.访问C#枚举 枚举值就像枚举类型下的静态属性一样。 testobj:EnumTestFunc(CS.Tutorial.TestEnum.E1) 上面的EnumTestFunc函数参数是Tutorial.TestEnum类型的 另外,如果枚举类加入到生成代码的话,枚举类将支持__CastFrom方法,可以实现从一个整数或者字符串到枚举值的转换,例如: CS.Tutorial.TestEnum.__CastFrom(1) CS.Tutorial.TestEnum.__CastFrom(‘E1’)
在Lua中有以下五种方法可以访问到枚举变量:
1当作普通的静态属性访问 2使用__CastFrom函数,从枚举值对应的数值做类型转换 3使用__CastFrom函数,从枚举值对应的字符串做类型转换 4直接传入枚举值对应的数值 5直接传入枚举值对应的字符串[LuaCallCSharp]public enum Language{ C_PLUS_PLUS, C_SHARP}[LuaCallCSharp]public class EnumParam{ public void PrintEnum(Language language) { switch(language){ case Language.C_PLUS_PLUS: Debug.Log("C++"); break; case Language.C_SHARP: Debug.Log("C#"); break; } }}
--访问枚举local enumParam=CS.EnumParam();local Language=CS.Language;--当作普通的静态属性访问enumParam:PrintEnum(Language.C_PLUS_PLUS);--直接传入枚举值对应的字符串enumParam:PrintEnum("C_SHARP")--直接传入枚举值对应的数值enumParam:PrintEnum(1);--使用__CastFrom函数,从枚举值对应的数值做类型转换enumParam:PrintEnum(Language.__CastFrom("C_PLUS_PLUS"));--使用__CastFrom函数,从枚举值对应的数值做类型转换enumParam:PrintEnum(Language.__CastFrom(1));04. 访问C#委托 delegate使用(调用,+,-) C#的delegate调用:和调用普通lua函数一样 +操作符:对应C#的+操作符,把两个调用串成一个调用链,右操作数可以是同类型的C# delegate或者是lua函数。 -操作符:和+相反,把一个delegate从调用链中移除。 Ps:delegate属性可以用一个luafunction来赋值。
[LuaCallCSharp]class DelegateClass{ public delegate void ActionString(string arg); public ActionString action = (arg) => { Debug.Log("action:" + arg); }; public ActionString actionString1 = (arg) => { Debug.Log("actionString1:" + arg); }; public ActionString actionString2 = (arg) => { Debug.Log("actionString2:" + arg); };}
--访问委托local delegateClass=CS.DelegateClass();--使用delegateClass类的对象访问委托变量actionlocal action1=delegateClass.action;action1("hi-1");--由于在Lua中没有"+="和"-="操作符,在增加委托链的时候只能使用"+"和"-"操作符action1=action1+delegateClass.actionString1+delegateClass.actionString2;action1("hi-2");action1=action1-delegateClass.actionString2;action1("hi-3");在使用Lua代码访问C#委托时需要注意,访问委托类型的方式与访问静态变量的方式相同,访问(静态/非静态)委托的变量的方式与访问(静态/非静态)成员变量的方式相同
--使用DelegateClass类访问委托类型ActionString,--定义一个ActionString类型的委托变量action2local DelegateClass=CS.DelegateClass;local delegateClass=CS.DelegateClass();---此时action2的值为nillocal action2=DelegateClass.ActionString;action2=delegateClass.actionString1;action2("hi-4");action2=action2+delegateClass.actionString2;action2("hi-5");05.访问C#事件 比如testobj里头有个事件定义是这样:public event Action TestEvent; 增加事件回调 testobj:TestEvent(’+’, lua_event_callback) 移除事件回调 testobj:TestEvent(’-’, lua_event_callback)
在访问C#事件的时候需要生成代码,所以必须要为事件的委托类型加上一个Attribute:[CSharpCallLua],关于为什么这里需要加[CSharpCallLua]而不是[LuaCallCSharp],在xLua的github主页的FAQ上作者是这么解释的:
LuaCallCSharp以及CSharpCallLua两种生成各在什么场景下用?
看调用者和被调用者,比如要在lua调用C#的GameObject.Find函数,或者调用gameobject的实例方法,属性等,GameObject类要加LuaCallSharp,而想把一个lua函数挂到UI回调,这是调用者是C#,被调用的是一个lua函数,所以回调声明的delegate要加CSharpCallLua。 有时会比较迷惑人,比如List.Find(Predicate match)的调用,List当然是加LuaCallSharp,而Predicate却要加CSharpCallLua,因为match的调用者在C#,被调用的是一个lua函数。 更无脑一点的方式是看到“This delegate/interface must add to CSharpCallLua : XXX”,就把XXX加到CSharpCallLua即可。[LuaCallCSharp]class EventClass{ //在访问C#事件的时候需要生成代码 //所以必须要为事件的委托类型加上一个Attribute:[CSharpCallLua], [CSharpCallLua] public delegate void EventAction(); public event EventAction Events; public EventAction action1 = () => { Debug.Log("action1"); }; public EventAction action2 = () => { Debug.Log("action2"); }; public void TriggerEvent() { Events(); }}
在添加事件的时候,既可以使用C#中的委托变量,也可以使用Lua中的函数
同时在添加和移除事件的时候应该使用以下的方式
object:event("+", delegate)
object:event("-", delegate)function lua_action() print("lua_action:")endlocal eventClass=CS.EventClass();eventClass:Events("+",lua_action);eventClass:Events("+",eventClass.action1);eventClass:Events("+",eventClass.action2);eventClass:TriggerEvent();
转载地址:http://nfrxo.baihongyu.com/