C#調用Lua
一.前提
這里使用的是XLua框架,需要提前配置xlua,設置加載器路徑;
可以參考之前的Blog:《xlua入門基礎》;
二.C#調用Lua全局變量
lua中所有的全局變量都會存在一個表中,對應xLua中的Global,通過lua解釋器返回出來;
通過Global的方法Get<類型>(key)調用;
--Lua代碼
num = 199
name = "littlePerilla"
hp = 2112.121
active = true
//c#代碼
private void Start()
{
XluaEnv.I.DoString("CSharpCallVariable");
LuaTable golbal = XluaEnv.I.Golbal();
int id = golbal.Get<int>("num");
string name = golbal.Get<string>("name");
float hp = golbal.Get<float>("hp");
bool active = golbal.Get<bool>("active");
Debug.Log(id + "," + name + "," + hp + "," + active);
}
調用lua中局部變量,通過table調用;
三.C#調用Lua全局方法
調用lua中方法和調用變量方式相同,返回值為委托類型;
1.無參數方法
--Lua代碼
func = function ()
print("lua函數")
end
Action act1 = golbal.Get<Action>("func");
act1();
2.帶參數方法
--Lua代碼
func2 = function(mName)
print(mName)
end
[CSharpCallLua]
public delegate void Func2(string name);
private void Start()
{
Func2 act3 = golbal.Get<Func2>("func2");
act3("littlePerilla");
}
3.多返回值
--Lua代碼
func1 = function()
return 1,2,3
end
1)使用委托
[CSharpCallLua]
public delegate void Func(out int a, out int b, out int c);
private void Start()
{
Func act3 = golbal.Get<Func>("func1");
int a,b,c;
act3(out a,out b,out c);
}
2)使用LuaFunction
LuaFunction act2 = golbal.Get<LuaFunction>("func1");
object[] objs = act2.Call();
foreach (var obj in objs)
{
Debug.Log(obj);
}
坑:這里使用委托必須要加[CSharpCallLua]特性,但是有時候加了也會失效,可能是xlua版本和Unity版本兼容問題;
四.C#調用Lua表
Lua中的table相當於C#中的類,調用表也就是調用類;
--lua代碼
tabe = {}
tabe.name = "littlePerilla"
tabe.hp = 100
tabe.attack = function (self)
return "展開了攻擊"
end
tabe.jump = function(self)
self = tabe
print(self.name.."跳了起來")
end
1.通過Class映射
[CSharpCallLua]
public class Role
{
[CSharpCallLua]
public delegate string Func1();
[CSharpCallLua]
public delegate void Func2();
public string name;
public int hp;
public Func1 attack;
public Func2 jump;
}
public class CSharpCallTable:MonoBehaviour
{
private void Start()
{
XluaEnv.I.DoString("CSharpCallTable");
LuaTable global = XluaEnv.I.Golbal();
//通過table和c#中類映射來調用
Role core = global.Get<Role>("tabe");
core.name = "SuperPerilla";
Debug.Log(core.name+","+core.hp);
Debug.Log(core.attack());
core.jump();
}
}
2.通過LuaTable
public class CSharpCallTable:MonoBehaviour
{
private void Start()
{
XluaEnv.I.DoString("CSharpCallTable");
LuaTable global = XluaEnv.I.Golbal();
//通過C#中luatable類型調用
LuaTable core2 = global.Get<LuaTable>("tabe");
core2.Set<string, string>("name", "SuperPerilla");
Func<string> osp = core2.Get<Func<string>>("attack");
Debug.Log(osp());
Action jump = core2.Get<Action>("jump");
jump();
}
}
坑:這兩個打印結果明顯不同,通過類映射調用,修改類對象的字段后,再調用lua方法,方法中使用了該字段,發現字段值並沒有改變,這應該是和lua中self的賦值有關系;
建議使用LuaTable來調用lua中的table;
但是據說通過結構體映射會減少Lua代碼調用的GC,需要加上特性[GCOptimize];