xLua中Lua調用C#
1.前提
這里使用的是XLua框架,需要提前配置xlua,設置加載器路徑;
可以參考之前的Blog:《xlua入門基礎》;
//調用端,所有的lua代碼都寫在LuaCallCSharp.lua文件中
public class LuaCallCSharp1 : MonoBehaviour
{
void Start()
{
XluaEnv.I.DoString("LuaCallCSharp");
}
private void OnDestroy()
{
XluaEnv.I.Free();
}
}
2.調用C#類
靜態類
public static class TestStatic
{
public static void ShowName(string name, int id)
{
Debug.Log($"name:{name},id:{id}");
}
}
--靜態類
CS.TestStatic.ShowName("littlePerilla",1012);
動態類
public class NPC
{
public string name;
public int attack;
public NPC(string name,int attack)
{
this.name = name;
this.attack = attack;
}
public int Hp { get; set; }
public void Attack()
{
Debug.Log($"attack:{attack},Hp:{Hp}");
}
}
--類對象
local hero = CS.NPC("Angel",100)
hero.Hp = 110
hero:Attack()
調用Unity官方Api
--創建物體
local go = CS.UnityEngine.GameObject("LuaObj ")
--添加組件
go:AddComponent(typeof(CS.UnityEngine.BoxCollider))
Lua不支持泛型,所有用到泛型的地方需要把每種可能的重載都寫一遍;
調用父類和子類
public class Father
{
public string name = "father";
public virtual void Say()
{
Debug.Log($"{name}:我在被調用");
}
}
public class Child :Father
{
public string name = "child";
public override void Say()
{
Debug.Log($"{name}:我在被調用");
}
}
local father = CS.Father()
father:Say()
local child = CS.Child()
child:Say()
類拓展方法
拓展類必須為靜態類,類必須加特性[LuaCallCSharp];《C#類拓展方法》;
會受到xlua版本和unity版本影響,導致調用失敗,xlua官方推薦版本是2017(太過時了);
public class TestExtension
{
public string Test1()
{
return "test";
}
}
[LuaCallCSharp]
public static class MyExtension
{
public static void Test2(this TestExtension obj)
{
Debug.Log("ExtensionFunc:"+ obj.Test1());
}
}
local testEx = CS.TestExtension()
print(testEx:Test1())
testEx:Test2()
3.調用C#結構體
結構體和類相似,都有構造方法;
public struct TestStruct
{
public int id;
public string name;
public void Output()
{
Debug.Log(id);
Debug.Log(name);
}
}
--結構體
local teststrut = CS.TestStruct()
teststrut.id = 12
teststrut.name = "littlePerilla"
teststrut:Output()
4.調用C#枚舉
枚舉使用的userdate自定義數據類型;
public enum State
{
idle = 0,
walk,
run,
attack
}
--枚舉使用的userdate自定義數據類型
local state = CS.State.idle
print(state)
--轉換獲得枚舉
print(CS.State.__CastFrom(1))
print(CS.State.__CastFrom("run"))
5.調用C#中委托
靜態委托賦值調用必須釋放;
動態委托不必要,但是最好也釋放;
調用委托前先做為空判定;
Lua中沒有+=或-=方法,只能通過a = a+b來實現多播;
public delegate void DelegateLua();
public class TestDelegate
{
public static DelegateLua deStatic;
public DelegateLua deDynamic;
public static void Func()
{
Debug.Log("靜態委托");
}
public void Func2()
{
Debug.Log("動態委托");
}
}
--靜態委托賦值調用必須釋放
CS.TestDelegate.deStatic = CS.TestDelegate.Func
CS.TestDelegate.deStatic()
CS.TestDelegate.deStatic = nil
local func = function ()
-- body
print("lua函數替換委托")
end
--lua函數賦值委托
CS.TestDelegate.deStatic = func
--多播委托,確定deStatic不為空,lua沒有+=和-=
if(CS.TestDelegate.deStatic ~= nil)then
CS.TestDelegate.deStatic = CS.TestDelegate.deStatic + func
else
CS.TestDelegate.deStatic = func
end
--調用前判定不為空
if(CS.TestDelegate.deStatic ~= nil)then
CS.TestDelegate.deStatic()
end
CS.TestDelegate.deStatic = nil
--動態委托
local test = CS.TestDelegate()
local func1 = function()
print("動態委托調用")
end
test.deDynamic = func1
test.deDynamic()
test.deDynamic = nil
6.調用C#事件
事件的調用不能直接復制,必須使用(“+”,function);
事件回調完成也需要釋放;
public delegate void EventLua();
public class TestEvent
{
public event EventLua luaEvent1;
public static event EventLua luaEvent2;
public static void Func()
{
Debug.Log("靜態事件");
}
public static void CallEvent2()
{
if (luaEvent2 != null)
luaEvent2();
}
public void CallEvent1()
{
if (luaEvent1 != null)
luaEvent1();
}
}
--靜態事件
CS.TestEvent.luaEvent2("+",CS.TestEvent.Func)
CS.TestEvent.CallEvent2()
CS.TestEvent.luaEvent2("-",CS.TestEvent.Func)
--動態事件
local test = CS.TestEvent()
local func = function ()
print("動態事件")
end
test:luaEvent1("+",func)
test:CallEvent1()
test:luaEvent1("-",func)