XLua 重写C#的一些注意

这两天正在学习XLua,正好线上版本有个BUG需要热更代码。将几个方法用Lua进行了重写,这里记录了几个作为一个lua新手遇到的几个问题。

首先是重写如下C#方法,该方法在BaseDance类里面,命名空间为Dance。

private Vector3 GetRankPos(int index, int count) {
    if(index == 0) {
        return Vector3.zero;
    }
    if(count == 3 || count == 2) {
        if(index == 1) {
            return new Vector3(1.7f, 0, -1f);
        }
        if(index == 2) {
            return new Vector3(-1.7f, 0, -1f);
        }
    }
    return new Vector3(-0.8f, 0, -2f);
}

对应的Lua为

xlua.hotfix(CS.Dance.BaseDance, 'GetRankPos', function(self, index, count)
	if index == 0 then
		return CS.UnityEngine.Vector3.zero;
	end
	
	if count == 3 or count == 2 then
		if index == 1 then
			return CS.UnityEngine.Vector3(1.7, 0, -1);
		end
		if index == 2 then
			return CS.UnityEngine.Vector3(-1.7, 0, -1);
		end
	end
	return CS.UnityEngine.Vector3(-0.8, 0, -2);
end)

先来看看官方给的Xlua的几个API,API链接

XLua 重写C#的一些注意_第1张图片

可以知道,我们现在要替换C#方法需要使用xlua.hotfix的API,第一个参数及GetRankPos所在的类(带命名空间,以CS.开头)即CS.Dance.BaseDance,第二个参数为方法名的string,即GetRankPos,第三个参数及对应的重写方法function了,要注意的是function重写方面里面的参数,第一个应该为self,后面的参数为原方法的参数。即function(self, index, count) end。

这个方法里面还需要注意的一点是,C#实例一个对象使用new字段,但是lua语言则不能添加new(因为lua中不存在类)。同时用到C#类的时候,不管是系统的还是自定义的同样需要已CS.NameSpace.ClassName的形式写

同时由于上述方法是private私有的。重写该方法时必须让其变为public公有的才行。根据api,我们还应该加上下面这一句

xlua.private_accessible(CS.Dance.BaseDance);


接下去需要新增一个变量,然后在如下方法给该变量赋值:

原c#代码

protected virtual void LoadStage() {
    stageAsset = new ModelAssetItem(ModelAssetHelp.SubFolder_Stage, danceParam.StageName);
    stageAsset.LoadModel(LoadStageFinish);
}

对应的lua代码

local m_isAllScroreZero;

xlua.hotfix(CS.Dance.BaseDance, "LoadStage", function(self)
    self.stageAsset = CS.Common.ModelAssetItem(CS.Common.ModelAssetHelp.SubFolder_Stage, self.danceParam.StageName);
    self.stageAsset:LoadModel(function ()
        self:LoadStageFinish();
    end);

    m_isAllScroreZero = true;
end)

这边需要注意的是,首先在Lua代码中调用原c#类自带的属性方法是,需要使用self字段。其中调用方法self:MethodName()等同于self.MethodName(self)。还有就是我们可以注意到LoadModel方法其实传的是一个Action参数,即穿了一个方法。而在lua中,不能直接self.stageAsset:LoadModel(self:LoadStageFinish());否则会报出如下错误:LuaException: c# exception:The Object you want to instantiate is null.,stack:  at UnityEngine.Object.CheckNullArgument。所以我们可以如上嵌套一个function来解决。


除了上面这些,还发现当lua调用c#的Mathf.Clamp01(float)方法时,无法返回到正确的值,一直是0.0。所以需要自己重新处理下。

你可能感兴趣的:(XLua)