lua5.1 - function env
注意:只在lua 5.1才支持,后面的lua版本做了改动不再兼容
myEnv.lua
local myEnv = {} myEnv.a = 1 myEnv.b = "one" myEnv.log = print return myEnv
Test.lua
local myEnv= require("myEnv") setfenv(1, myEnv) --调用上面的函数后, print将没法使用因为那是在全局env下, --现在切换为自定义的env了, 只能访问到自定env提供的值 --print("123") --_G.print("123") function Test1() log(a) log(b) end Test1()
关于setfenv(func or number,tbl)
1) 第1个参数为数字时,1表示修改当前作用域的env,2表示修改上层作用域的,以此类推。特殊情况是0,表示修改当前运行线程的。
2) 第2个参数为新env的table
一些用法
1) 参考xlua的LuaBehaviour:向C#脚本关联的lua脚本注入c#对象
[System.Serializable] public class BindObject { public string Name; public UnityEngine.Object Obj; } public class MyLuaBehaviour : MonoBehaviour { [SerializeField] internal BindObject[] m_BindObjects; [SerializeField] internal string m_ScriptPath; private Dictionary<string, UnityEngine.Object> m_BindObjDict; private LuaTable m_MonoTable; private Action m_LuaOnEnable; private Action m_LuaStart; private Action m_LuaOnDisable; private Action m_LuaOnDestroy; private Action m_LuaUpdate; private Action m_LuaLateUpdate; void Awake() { OnAwake(); } protected virtual void OnAwake() { var luaEnv = LuaManager.Instance.LuaEnv; if (null == luaEnv) return; m_MonoTable = luaEnv.NewTable(); var mt = luaEnv.NewTable(); mt.Set("__index", luaEnv.Global); //mt上找不到的, 去global找 m_MonoTable.SetMetaTable(mt); mt.Dispose(); m_MonoTable.Set("self", this); //注入lua Table foreach (var item in m_BindObjects) { if (string.IsNullOrEmpty(item.Name) || null == item.Obj) continue; m_MonoTable.Set(item.Name, item.Obj); } if (string.IsNullOrEmpty(m_ScriptPath)) return; var txtAsset = AssetDatabase.LoadAssetAtPath<TextAsset>(m_ScriptPath); if (null == txtAsset || string.IsNullOrEmpty(txtAsset.text)) return; luaEnv.DoString(txtAsset.text, m_ScriptPath, m_MonoTable); //脚本中不存在的字段, 会先在env对象上找, 没找到再去_Global对象上找 Action luaAwake = null; m_MonoTable.Get("Awake", out luaAwake); m_MonoTable.Get("OnEnable", out m_LuaOnEnable); m_MonoTable.Get("Start", out m_LuaStart); m_MonoTable.Get("OnDisable", out m_LuaOnDisable); m_MonoTable.Get("OnDestroy", out m_LuaOnDestroy); m_MonoTable.Get("Update", out m_LuaUpdate); m_MonoTable.Get("LateUpdate", out m_LuaLateUpdate); SafeInvoke(luaAwake); } void OnEnable() { SafeInvoke(m_LuaOnEnable); } void Start() { SafeInvoke(m_LuaStart); } void OnDisable() { SafeInvoke(m_LuaOnDisable); } void OnDestroy() { SafeInvoke(m_LuaOnDestroy); if (null != m_MonoTable) m_MonoTable.Dispose(); m_MonoTable = null; m_LuaOnDestroy = null; m_LuaOnDisable = null; m_LuaStart = null; m_LuaOnEnable = null; } public void OnUpdate() { SafeInvoke(m_LuaUpdate); } public void OnLateUpdate() { SafeInvoke(m_LuaLateUpdate); } public UnityEngine.Object GetObject(string name) { if (null == m_BindObjDict) { m_BindObjDict = new Dictionary<string, UnityEngine.Object>(); for (var i = 0; i< m_BindObjects.Length; ++i) { var item = m_BindObjects[i]; if (null == item.Obj || string.IsNullOrEmpty(item.Name)) continue; m_BindObjDict.Add(item.Name, item.Obj); } } m_BindObjDict.TryGetValue(name, out var obj); return obj; } private void SafeInvoke(Action func) { if (null == func) return; try { func(); } catch (Exception ex) { Debug.LogError($"{ex.GetType().Name}: {ex.Message}"); } } }
分类:
lua
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 因为Apifox不支持离线,我果断选择了Apipost!
· 通过 API 将Deepseek响应流式内容输出到前端
2021-03-03 错误处理 pcall, xpcall