XLua遇坑总结(不定期更)

来源:互联网 发布:东莞seo公司 编辑:程序博客网 时间:2024/05/16 06:10

1.NGUI通过lua层为按钮设置lua中点击回调方法时,需要把存储当前回调事件的脚本记录到list中,并在该LuaEnv Dispose()之前将所有onClick = null,否则会导致xlua抛出”try to dispose a LuaEnv with C# callback!” 异常
参考链接:http://www.cnblogs.com/ghl_carmack/p/7350530.html

参考代码:

private List<UIEventListener> ButtonEventListener = new List<UIEventListener>();/// <summary>/// 添加单击事件/// </summary>public void AddClick(GameObject go,UIEventListener.VoidDelegate luafunc) {       if (go == null || luafunc == null) return;       UIEventListener uievent = UIEventListener.Get(go);       uievent.onClick = delegate(GameObject o) {           luafunc(go);       };       ButtonEventListener.Add(uievent);}/// <summary>/// 清除单击事件/// </summary>public void ClearClick() {      foreach (var listener in ButtonEventListener)      {          listener.onClick = null;      }      ButtonEventListener.Clear();}void OnDestroy() {    ClearClick() ;    luaEnvironment.Dispose();}

2.C# Call Lua 时的面向对象
(每个c#脚本对应一个lua文件,并且会重名)
lua中初始化代码如下:

Skill_10101 ={    skillObj = 0}-- 这句是重定义元表的索引,就是说有了这句,这个才是一个类。Skill_10101.__index = Skill_10101-- 构造体,构造体的名字是随便起的,习惯性改为New()function Skill_10101:New(sObj)    local self = { };    -- 初始化self,如果没有这句,那么类所建立的对象改变,其他对象都会改变    setmetatable(self, Skill_10101);    -- 将self的元表设定为Class    self.skillObj = sObj;    return self;end

当c#脚本初始化时读取对应lua文件,代码如下:

    public static string LuaStr = "Skill_";    public string LuaName { get { return LuaStr + this.SkillMode.dataBase.id; } }    // 对应该lua文件        private LuaTable _luaSkill = null;    // 对应该lua New出来的对象    private LuaTable _luaTableObject;    public LuaTable LuaTable    {        get        {            if (_luaSkill == null && _isExistLuaFile)            {                try                {                    ManagerUtil.LuaManager.RequireFile("Skill/" + LuaName);                    _luaSkill = ManagerUtil.LuaManager.GlobleLuaEnvTable.Get<LuaTable>(LuaName);                    //如果读取失败,说明不存在这个lua技能 择全部跳过                    _isExistLuaFile = _luaSkill != null;                    if (_isExistLuaFile)                    {                        // New一个luaTable对象 并在c# call lua 方法时将该对象传入第一个参数                        var tab = _luaSkill.Get<LuaFunction>("New").Call(_luaSkill, this);                        _luaTableObject = (LuaTable) tab[0];                    }                }                catch                {                    _isExistLuaFile = false;                }            }            return _luaSkill;        }    }/// 回调lua中代码/// 可以理解为从一个class中查找到该成员方法/// 然后使用该class提前new出的对象调用该成员方法public void CallLuaFunction(string FunName){    if (this.LuaTable != null)    {       var func = this.LuaTable.Get<LuaFunction>(funcName);       if (func != null)       {           func.Call(_luaTableObject);       }    }}

3.C#调用lua传递参数问题
之前项目用ToLua时候,C#调用lua中的方法可以交给C#中的LuaManager读取lua方法,对应的lua参数是以params object[]形式传递进来的,但是换了xlua以后,必须直接将参数传递给LuaFunction调用,也就是说不允许在C#层将参数二次装箱处理,否则lua中只能读取出一个参数,并且为userdata类型.

// ToLua:// 该方法写在lua管理类即可,其他C#脚本直接调用该方法// 传递进的参数装箱为params object[]形式 再次传入LuaFunctionpublic void CallLuaFunction(string FunName,params object[] args){    if (this.LuaTable != null)    {       var func = this.LuaTable.Get<LuaFunction>(funcName);       if (func != null)       {           func.Call(_luaTableObject,args);       }    }}// XLua:// 在每个调用lua方法的C#脚本中单独写出对应方法// 由LuaFunction做装箱操作,直接传入params object[]型参数lua会读取错误public void CallLuaFunction(string FunName,GameObject obj){    if (this.LuaTable != null)    {       var func = this.LuaTable.Get<LuaFunction>(funcName);       if (func != null)       {           func.Call(_luaTableObject,obj);       }    }}
原创粉丝点击