思路:新建一个通用的LuaCustomCommon类挂在需要用lua实现逻辑的prefab上。通过这个组件关联名为Panel的lua脚本,生成对应的LuaTable,通过这个组件为lua赋值对应prefab的属性,并在Start(),Update()等生命周期方法中通过LuaTable.Get(“MethodName”);调用lua中对应的方法。在lua中使用transform:Find(“name”)来关联prefab中的组件,通过这个LuaCustomCommon类就可以把前端的逻辑放在Lua脚本中。
先写一个通用的管理类用来管理Xlua:
public class XluaCommon
{
private static XluaCommon _instance;
public static XluaCommon Instance
{
get
{
if (_instance==null)
{
_instance = new XluaCommon();
}
return _instance;
}
}
public LuaEnv luaEnv
{
private set;
get;
}
public XluaCommon()
{
luaEnv = new LuaEnv();
luaEnv.AddLoader(CustomerLoader);
}
//自定义Load
byte[] CustomerLoader(ref string flie)
{
string fliePath = Application.dataPath + "/Scripts/luaTxt/" + flie + ".lua.txt";
return System.Text.Encoding.UTF8.GetBytes(File.ReadAllText(fliePath));
}
//加载lua表
public void LoadLuaTable(string name)
{
if (string.IsNullOrEmpty(name))
{
Debug.Log("name is null");
return;
}
string flieName = string.Format("require'{0}'",name);
luaEnv.DoString(flieName);
}
//得到Lua表
public LuaTable GetLuaTable(string name,string Testid)
{
if (string.IsNullOrEmpty(name))
{
Debug.Log("name is null");
return null;
}
LuaTable table = luaEnv.Global.Get<LuaTable>(name);
if (table==null)
{
//加载
LoadLuaTable(name);
table = luaEnv.Global.Get<LuaTable>(name);
}
return table;
}
// delegate void test(int id);
public void Dispose()
{
Dispose(true);
}
private void Dispose(bool isDispose)
{
if (isDispose)
{
if (luaEnv!=null)
{
luaEnv.GC();
luaEnv.Dispose();
}
}
//置空
luaEnv = null;
_instance = null;
}
//回收
~XluaCommon()
{
Dispose(false);
}
}
通用的LuaCustomCommon类:
public class LuaCustomCommon : MonoBehaviour
{
//定义的Lua文件名字
public string luaPanelName;
Action lua_Update;
public LuaTable luaTable
{
private set;
get;
}
public bool LoadLuaFile()
{
if (string.IsNullOrEmpty(luaPanelName))
{
Debug.Log("luaPanelName is null");
return false;
}
string s = "id";
luaTable = XluaCommon.Instance.GetLuaTable(luaPanelName,s);
if (luaTable==null)
{
Debug.Log("luaTable is null");
return false;
}
luaTable.Set("transform", transform);
lua_Update = luaTable.Get<Action>("Update");
return true;
}
//调用Lua中的方法
private void CallLuaFunction(string Name)
{
if (string.IsNullOrEmpty(Name))
{
Debug.Log("luafunction is null");
return;
}
Action func = luaTable.Get<Action>(Name);
// Debug.Log("func:"+(func==null)+" 原luaTable:"+ (luaTable==null));
if (func != null)
{
func();
}
}
private void Awake()
{
if (LoadLuaFile())
{
//Debug.Log("Awake为true!");
CallLuaFunction("awake");
}
else
{
Debug.Log("加载" + luaPanelName + "文件失败");
}
}
void Start()
{
//如果是 Add component 的情况,会导致Tabel = null 应该在Add component 后调用一次LoadLuaFile()
if (luaTable==null)
{
if (string.IsNullOrEmpty(luaPanelName))
{
Debug.Log("luaPanelName is null");
return;
}
if (!LoadLuaFile())
{
Debug.Log("LoadLuaFile is false");
return;
}
}
CallLuaFunction("start");
}
void Update()
{
if (lua_Update!=null)
{
lua_Update();
}
}
private void OnEnable()
{
CallLuaFunction("onEnable");
}
private void OnDisable()
{
CallLuaFunction("onDisable");
}
private void OnDestroy()
{
CallLuaFunction("onDestroy");
lua_Update = null;
luaTable.Dispose();
luaTable = null;
}
}
Lua脚本代码:
Panel={}
this=Panel
print("加载成功!")
function this.awake()
print('awake')
end
function this.start()
print('Start')
end
function this.Update()
print("update!")
end
function this.onEnable()
print('OnEnable')
end
function this.onDisable()
print('OnDisable')
end
function this.onDestroy()
print('OnDestroy')
end
脚本挂载的位置:
输出结果: