上一篇文章:
Unity XLua学习笔记(一):创建脚本,完成准备工作
C#获取Lua中的变量
注意:这篇文章中所用到的变量调用均为值拷贝,并不能改变Lua脚本中的值,除了接口拷贝(引用拷贝,会改变Lua中的值)
在TestLua中定义一些变量
print("LuaTest")
testInt=10
testStr="ABC"
testBool=true
testFloat=1.2
--无参数无返回值的函数
testFun1=function()
print("无参无返回函数")
end
--有参数无返回值的函数
testFun2_1=function(a)
print("有参无返回函数,参数:"..a)
end
--有参数无返回值的函数
testFun2_2=function(a,b)
print("有参无返回函数,参数1:"..a.."参数2:"..b)
end
--有参数有返回
testFun2_3=function(a)
return a
end
--多返回值的函数
testFun3=function(a)
return 100,200,false,"字符",a
end
--变长参数函数1
testfun4_1=function(...)
arg={...}
for k,v in pairs(arg) do
print(k,v)
end
end
--变长参数函数2
testfun4_2=function(a,...)
print("变长参数的固定参数:"..a)
arg={...}
for k,v in pairs(arg) do
print(k,v)
end
end
--C#无法直接获取Lua中的本地变量
local testLocal=20
一般写法
LuaEnv luaEnv=new LuaEnv();
luaEnv.AddLoader(CustomLoader_Editor);
luaEnv.AddLoader(CustomLoader_StreamingAssets);
luaEnv.DoString("require('Main')");
//调用Int变量
int Lua_Int= luaEnv.Global.Get<int>("testInt");
Debug.Log("Lua中的Int变量:"+Lua_Int);
为了方便,我就直接用上篇文章中的XLua脚本管理器写了
首先声明委托,用来存储Lua中的方法
lua脚本内容:
--无参数无返回值的函数
testFun1=function()
print("无参无返回函数")
end
--有参数无返回值的函数
testFun2_1=function(a)
print("有参无返回函数,参数:"..a)
end
--有参数无返回值的函数
testFun2_2=function(a,b)
print("有参无返回函数,参数1:"..a.."参数2:"..b)
end
testFun2_3=function(a)
return a
end
--多返回值的函数
testFun3=function(a)
return 100,200,false,"字符",a
end
C#中的委托:
注意,除了无参无返回值的委托,剩下的委托都要加上[CSharpCallLua]
//无参无返回值
//XLua已经处理了无参无返回的委托,不需要加[CSharpCallLua]
public delegate void CustomCall();
//有参无返回,一个参数
[CSharpCallLua]
public delegate void CustomCall_v1(int a);
//有参无返回,两个参数
[CSharpCallLua]
public delegate void CustomCall_v2(int a,int b);
//有参有返回,一个返回
[CSharpCallLua]
public delegate int CustomCall_v_r1(int a);
//因为第一个返回值是number,这里采用int
//一共有5个返回值,第一个作为函数默认的返回值,后面有几个返回值就加几个out,并对应类型
[CSharpCallLua]
public delegate int CustomCall_v_mr(int a,out int b,out bool c,out string d,out int e);
调用方法类似变量
//无参返回
CustomCall call=XLuaMgr.GetInstance().Global.Get<CustomCall>("testFun1");
call();
//有参无返回,一个参数
CustomCall_v1 call_v1=XLuaMgr.GetInstance().Global.Get<CustomCall_v1>("testFun2_1");
call_v1(123);
//有参无返回,两个参数
CustomCall_v2 call_v2=XLuaMgr.GetInstance().Global.Get<CustomCall_v2>("testFun2_2");
call_v2(111,222);
//有参数有返回值 一个返回值
CustomCall_v_r1 call_v_r1=XLuaMgr.GetInstance().Global.Get<CustomCall_v_r1>("testFun2_3");
Debug.Log("有参有返回值的函数:"+call_v_r1(456));
//多返回值函数用out来接收
CustomCall_v_mr call_v_mr=XLuaMgr.GetInstance().Global.Get<CustomCall_v_mr>("testFun3");
int a,b;
bool c;
string d;
int e;
Debug.Log(call_v_mr(1,out b,out c,out d,out e));
运行前记得执行XLua------>Generate Code,不然直接运行会报错,因为我们将委托打上了[CSharpCallLua],所以需要XLua生成相应代码
运行后打印:
变长函数委托
//变长参数的类型根据实际情况设定,通用情况用object,但会增加开销
[CSharpCallLua]
public delegate void CustomCall_mv(params object[] args);
//变长参数+固定参数
[CSharpCallLua]
public delegate void CustomCall_mv_2(int a,params object[] args);
调用Lua中的变长参数
//变长参数
CustomCall_mv call_mv=XLuaMgr.GetInstance().Global.Get<CustomCall_mv>("testfun4_1");
call_mv(1,2,3,4,5,"AA",true);
//变长参数+固定参数
CustomCall_mv_2 call_mv_2=XLuaMgr.GetInstance().Global.Get<CustomCall_mv_2>("testfun4_2");
call_mv_2(100,1,2,3,4,5,"AA",true);
lua代码
--List
testList={11,22,33,44,55,66}
testList2={"ABCD",123,true,11,1.23}
testDic={
["1"]=11,
["2"]=22,
["3"]=33,
["4"]=44
}
C#代码
Debug.Log("**********List***********");
List<int> list=XLuaMgr.GetInstance().Global.Get<List<int>>("testList");
for(int i=0;i<list.Count;i++)
{
Debug.Log("List: "+ list[i]);
}
List<object> list2=XLuaMgr.GetInstance().Global.Get<List<object>>("testList2");
for(int i=0;i<list2.Count;i++)
{
Debug.Log("objectList: "+list2[i]);
}
Debug.Log("**********Dictionary***********");
Dictionary<string,int> dic=XLuaMgr.GetInstance().Global.Get<Dictionary<string,int>>("testDic");
foreach(string item in dic.Keys)
{
Debug.Log("Dic: "+item+"_"+dic[item]);
}
Lua代码
testClass={
testInt=2,
testBool=true,
testFloat=1.2,
testString="123",
testFun=function()
print("lua中的类方法执行")
end
}
C#代码
示例类
public class CallLuaClass
{
//在这个类中去声明成员变量
//名字一定要和Lua那边一样
//公共 私有和保护没办法赋值
//这个自定义中的 变量 可以更多也可以更少
//如果变量比 lua中的少 就会忽略它
//如果变量比 lua中的多 不会赋值 也会忽略
public int testInt;
public bool testBool;
public float testFloat;
public float testString;
public UnityAction testFun;
public CallLuaInClass testInClass;
public int i;
public void Test()
{
Debug.Log(testInt);
}
}
public class CallLuaInClass
{
public int testInClass;
}
调用
CallLuaClass obj = LuaMgr.GetInstance().Global.Get<CallLuaClass>("testClass");
Debug.Log(obj.testInt);
Debug.Log(obj.testBool);
Debug.Log(obj.testFloat);
Debug.Log(obj.testString);
Debug.Log(obj.i);
示例接口
//接口中不允许有成员变量
//我们用属性来接收
//接口和类的规则一样 其中的的属性多了少了不影响结果 无法就是忽略他们
//嵌套几乎和类一样 无法是要遵循接口的规则
//如果接口中的内容变了,需要重新清理代码再生成代码
[CSharpCallLua]
public interface ICSharpCallInterface
{
int testInt
{
get;
set;
}
bool testBool
{
get;
set;
}
float testFloat
{
get;
set;
}
//string testString
//{
// get;
// set;
//}
UnityAction testFun
{
get;
set;
}
string test222
{
get;
set;
}
}
Lua中的类
testClass={
testInt=2,
testBool=true,
testFloat=1.2,
testString="123",
testFun=function()
print("123123")
end
}
C#调用
ICSharpCallInterface obj = XLuaMgr.GetInstance().Global.Get<ICSharpCallInterface>("testClass");
Debug.Log(obj.testInt);
Debug.Log(obj.testBool);
Debug.Log(obj.testFloat);
Debug.Log(obj.test222);
obj.testFun();
//接口拷贝 是引用拷贝 改了值 lua表中的值也变了
obj.testInt = 10000;
ICSharpCallInterface obj2 = XLuaMgr.GetInstance().Global.Get<ICSharpCallInterface>("testClass");
Debug.Log(obj2.testInt);