找回密码
 立即注册
查看: 420|回复: 0

XLua 重写C#的一些注意

[复制链接]
发表于 2021-8-12 17:30 | 显示全部楼层 |阅读模式
这两天正在学习XLua,正好线上版本有个BUG需要热更代码。将几个方法用Lua进行了重写,这里记录了几个作为一个lua新手遇到的几个问题。
首先是重写如下C#方法,该方法在BaseDance类里面,命名空间为Dance。
  1. private Vector3 GetRankPos(int index, int count) {
  2.     if(index == 0) {
  3.         return Vector3.zero;
  4.     }
  5.     if(count == 3 || count == 2) {
  6.         if(index == 1) {
  7.             return new Vector3(1.7f, 0, -1f);
  8.         }
  9.         if(index == 2) {
  10.             return new Vector3(-1.7f, 0, -1f);
  11.         }
  12.     }
  13.     return new Vector3(-0.8f, 0, -2f);
  14. }
复制代码
对应的Lua为
  1. xlua.hotfix(CS.Dance.BaseDance, 'GetRankPos', function(self, index, count)
  2.         if index == 0 then
  3.                 return CS.UnityEngine.Vector3.zero;
  4.         end
  5.        
  6.         if count == 3 or count == 2 then
  7.                 if index == 1 then
  8.                         return CS.UnityEngine.Vector3(1.7, 0, -1);
  9.                 end
  10.                 if index == 2 then
  11.                         return CS.UnityEngine.Vector3(-1.7, 0, -1);
  12.                 end
  13.         end
  14.         return CS.UnityEngine.Vector3(-0.8, 0, -2);
  15. end)
复制代码
先来看看官方给的Xlua的几个API,API链接


可以知道,我们现在要替换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,我们还应该加上下面这一句
  1. xlua.private_accessible(CS.Dance.BaseDance);
复制代码
接下去需要新增一个变量,然后在如下方法给该变量赋值:
原c#代码
  1. protected virtual void LoadStage() {
  2.     stageAsset = new ModelAssetItem(ModelAssetHelp.SubFolder_Stage, danceParam.StageName);
  3.     stageAsset.LoadModel(LoadStageFinish);
  4. }
复制代码
对应的lua代码
  1. local m_isAllScroreZero;
  2. xlua.hotfix(CS.Dance.BaseDance, "LoadStage", function(self)
  3.     self.stageAsset = CS.Common.ModelAssetItem(CS.Common.ModelAssetHelp.SubFolder_Stage, self.danceParam.StageName);
  4.     self.stageAsset:LoadModel(function ()
  5.         self:LoadStageFinish();
  6.     end);
  7.     m_isAllScroreZero = true;
  8. 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。所以需要自己重新处理下。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Unity开发者联盟 ( 粤ICP备20003399号 )

GMT+8, 2024-11-24 09:35 , Processed in 0.088441 second(s), 26 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表