@leviyuan
2017-09-13T09:30:41.000000Z
字数 4221
阅读 364
lua ui supermobs
使用FairyGUI引擎 http://www.fairygui.com/
使用配置表来替代之前 init.lua 中配置
- 优点:参数配置更加灵活
- 缺点:修改配置表容易冲突,需要注意excel冲突的解决
ui界面配置表目录: trunk\Desginer\Plan\10数据表\UI配置.xlsx
主要含两个配置表
uipackage 负责包的参数
uiconfig 负责UI界面参数配置
![]()
parentwin 主要存在目的在于通用公共的弹窗动画,用自界面的方式添加到父界面上
举例

界面脚本被闭包括起来,可以读取全局环境,但不可以直接修改全局环境,所有的global写操作都会卸载ui逻辑对象上
-- 初始化界面function initcom()herobtn = getchild("pannel/herobtn") --mainview:GetChild("pannel"):GetChild("herobtn")herobtn.onClick:Add(function() -- 为按钮添加监听ui.open("hero", 1) -- 打开hero界面,并且传一个参数 1end)pvebtn = mainview:GetChild("pvebtn")end-- 界面显示出来时候调用,会接到透穿参数function show(p1, p2)print("open params", p1, p2)end-- 被关闭时调用,可选,mainview已经被释放function onclose()print("home ui closed")end-- 自定义方法function customfunc(...)end
产生原因
lua和c#都是高级语言,有自动gc机制存在
自动gc的判断规则都是从全局变量开始递归,查找被引用的对象
最终没有被递归进来的对象就是垃圾,被gc掉
在lua+tolua+c#的模式下,c#可能会引用luafunction,luafunction也可能引用c#Object
在fairygui的ui对象,往往会添加侦听函数luafunction,界面关闭时,ui对象引用了luafunction,luafunction引用了uiobj,uiobj中又引用了ui对象,就这样形成了一个循环
解决方案
打破导致循环引用中的任何一个点,所有的东西都会被自动gc掉
现在采用隐式的方案来解决这个问题(只在ui脚本中有效,不在ui脚本中时,需要自行理解来处理)
可以扩展delegate类型和fairyguiObject的function类型的属性
-- supermobs/ui/fairygui.lua-- [[显式强转delegate类型时,为luafunction添加一层包装 tocfunc界面关闭时,释放tocfunc与实际的luafunction之间的关联,将循环引用的闭环打破]]-- ui auto release delegatelocal delegates = {"EventCallback1", "PlayCompleteCallback"}for _,dname in ipairs(delegates) dolocal raw = FairyGUI[dname]FairyGUI[dname] = function(func, obj)local env = getfenv(func)local tocfunc = funcif env ~= _G and env.__releasefuncs thentable.insert(env.__releasefuncs, function()func = nilobj = nilenv = nilend)tocfunc = function(...) if func then func(...) end endendreturn obj == nil and raw(tocfunc) or raw(tocfunc, obj)endend-- [[这里是一些直接赋值luafunction到c#的包装原理与delegate相同]]-- lua function to c#local setkey, getkeydolocal lud = {}for k,v in pairs(getmetatable(GLabel)) doif type(k) == "userdata" and type(v) == "table" thentable.insert(lud, k)endend-- 内存地址值较小的是setkey,较大的是getkeyif tonumber(tostring(lud[1]):sub(10)) < tonumber(tostring(lud[2]):sub(10)) thensetkey, getkey = lud[1], lud[2]elsesetkey, getkey = lud[2], lud[1]endendlocal funcpropertys = {{GList, "itemRenderer"}, {GList, "itemProvider"}}for _,item in ipairs(funcpropertys) dolocal tab = getmetatable(item[1])[setkey]local rawfunc = tab[item[2]]tab[item[2]] = function(self, func)local env = getfenv(func)local tocfunc = funcif env ~= _G and env.__releasefuncs thentable.insert(env.__releasefuncs, function()func = nilenv = nilend)tocfunc = function(...) if func then func(...) end endendreturn rawfunc(self, tocfunc)endend