CS:
using System.Collections; using System.Collections.Generic; using UnityEngine; using System; using XLua; // 注入Lua的数据 [System.Serializable] public class Injection { public string name; public GameObject value; } public class SceneManager : MonoBehaviour { public TextAsset luaScript; // Lua脚本 public Injection[] injections; internal static LuaEnv luaEnv = new LuaEnv(); // 全局唯一的Lua环境 private LuaTable scriptEnv; // 脚本环境 internal static float lastGCTime = 0; internal const float GCInterval = 1; // 垃圾回收间隔? // 在Lua端定义的函数 private Action luaStart; private Action luaUpdate; private Action luaOnDestroy; private void Awake() { Debug.Log("CS Awake"); scriptEnv = luaEnv.NewTable(); // 设置元表这一步是必需的 LuaTable meta = luaEnv.NewTable(); // 元表 meta.Set("__index", luaEnv.Global); // 元表的__index是Lua全局环境,这样才能访问到print这样的函数 scriptEnv.SetMetaTable(meta); // 设置元表 meta.Dispose(); // 在这里就直接弃用吗? // 注入数据:设置在Lua端能够读取到的数据 scriptEnv.Set("self", this); scriptEnv.Set("Key", 19437); // 随便传递一个数据进去,在Lua端就能读取到 foreach (var injection in injections) { scriptEnv.Set(injection.name, injection.value); } // Lua脚本也像CS的MonoBehaviour一样写,没有入口代码,都是函数定义 luaEnv.DoString(luaScript.text, luaScript.name, scriptEnv); // Lua的脚本环境有值之后,就可以获取函数并绑定了 Action luaAwake = scriptEnv.Get<Action>("awake"); scriptEnv.Get("start", out luaStart); scriptEnv.Get("update", out luaUpdate); scriptEnv.Get("ondestroy", out luaOnDestroy); if (luaAwake != null) { luaAwake(); } } // Start is called before the first frame update void Start() { Debug.Log("CS Start"); /* // 一个最简单的例子 XLua.LuaEnv luaenv = new XLua.LuaEnv(); // 一个LuaEnv实例对应Lua虚拟机,出于开销的考虑,建议全局唯一 luaenv.DoString("CS.UnityEngine.Debug.Log('hello world')"); luaenv.Dispose(); */ if (luaStart != null) { luaStart(); } } // Update is called once per frame void Update() { if (luaUpdate != null) { luaUpdate(); } if (Time.time - SceneManager.lastGCTime > GCInterval) { luaEnv.Tick(); // 这样就能触发Lua的GC吗? SceneManager.lastGCTime = Time.time; } } void OnDestroy() { if (luaOnDestroy != null) { luaOnDestroy(); } // 清空Action绑定 luaOnDestroy = null; luaUpdate = null; luaStart = null; // 销毁脚本环境 scriptEnv.Dispose(); injections = null; } }
Lua:
-- Lua端定义的函数都是全局的 function awake() print("lua awake...") end function start() print("lua start...") print('Key = '..Key) end function update() end function ondestroy() print("lua destroy...") end