LuaBehavior 繼承 MonoBehaviour 在Lua裡面實作 Start Update等Function
LuaBehavior .cs
using SLua;
using System;
using System.Collections;
using System.IO;
using UnityEngine;
[CustomLuaClass]
public class LuaBehavior : MonoBehaviour
{
LuaSvr svr;
LuaTable self;
[CustomLuaClass]
public delegate void UpdateDelegate(object self);
UpdateDelegate ud;
[CustomLuaClass]
public delegate void StartDelegate(object self);
StartDelegate sd;
[CustomLuaClass]
public delegate void DestoryDelegate(object self);
DestoryDelegate destoryDele;
[SerializeField]
string fileName;
Action initCompleteAction;
public virtual void Awake()
{
svr = new LuaSvr();
svr.init(tick, InitComplete);
LuaState.main.loaderDelegate += LuaLoader;
}
void tick(int p)
{
Debug.Log($"Lua init Progress {p}");
}
void InitComplete()
{
self = svr.start(fileName) as LuaTable;
ud = functionCast<UpdateDelegate>("update");
sd = functionCast<StartDelegate>("start");
destoryDele = functionCast<DestoryDelegate>("destory");
initComplete();
}
[DoNotToLua]
public virtual void initComplete() { }
[DoNotToLua]
public byte[] LuaLoader(string fn, ref string absoluteFn)
{
if (string.IsNullOrEmpty(fn))
{
Debug.LogError($"Get Lua File Name is Empty");
return new byte[] { };
}
string path = $"{Directory.GetCurrentDirectory()}/Assets/Script/Lua/{fn}.txt";
return File.ReadAllBytes(path);
}
public virtual void Start()
{
StartCoroutine(waitStart());
}
IEnumerator waitStart()
{
while (sd == null)
yield return null;
sd(self);
}
void Update()
{
if (ud == null)
return;
ud(self);
}
private void OnDestroy()
{
if (destoryDele == null)
return;
destoryDele(self);
}
T functionCast<T>(string tableName) where T : class
{
LuaFunction luaFunction = (LuaFunction)self[tableName];
if (luaFunction == null)
{
Debug.LogError($"Get {tableName} LuaFunction is null");
}
return luaFunction.cast<T>();
}
}
Lua寫法 TestLua.txt
function main()
print("lua--- run lua main function")
class.testMain = GameObject.Find("Main"):GetComponent("MainTest")
return class
end
-- 在C#的Update函数中被调用
function class:update()
time = time + Time.deltaTime
end
function class:start()
print("Start Run")
end
function class:destory()
print("destory")
end
另外一種不使用委託寫法
LuaBehavior .cs 修改為
public LuaFunction getLuaFunction(string key)
{
return svr.luaState.getFunction(key);
}
public virtual void Start()
{
StartCoroutine(waitStart());
}
IEnumerator waitStart()
{
while (self == null)
yield return null;
getLuaFunction("start").call();
}
void Update()
{
if (self == null)
return;
getLuaFunction("update").call();
}
private void OnDestroy()
{
if (self == null)
return;
getLuaFunction("destory").call();
}
Lua修改寫法 TestLua.txt
-- 在C#的Update函数中被调用
function update()
time = time + Time.deltaTime
end
function start()
print("Start Run")
end
function destory()
print("destory")
end
但不使用委託的方法下 依照slua GitHub裡面的說法 有可能會導致額外的box , unbox的gc alloc風險
所以導出對應的delegate 並轉換成luafunction為對應的delegate 就可以避免gc alloc的開銷
補充:
[CustomLuaClass] 此特性可以修飾類別註冊到SLua執行環境中 如果沒有加上 要呼叫類別必須用字串方式呼叫
function main()
print("lua--- run lua main function")
class.testMain = GameObject.Find("Main"):GetComponent("MainTest")
print("Print Log"..class.testMain == nill)
return class
end
否則會報錯
有加上可以用以下方式呼叫
function main()
print("lua--- run lua main function")
class.testMain = GameObject.Find("Main"):GetComponent(MainTest)
print("Print Log"..class.testMain == nill)
return class
end