Xlua 打补丁流程实验记录

概述

首先将xLua-master里的Assets文件夹下的四个文件夹导入到unity项目里,然后在PlayerSetting里面添加HOTFIX_ENABLE宏。
xlua还需要依赖unity的cecil的dll程序集,这个需要到unity的安装目录下去复制。
具体是在安装文件夹下的Editor\Data\Managed下,分别是:Unity.Cecil.dll,Unity.Cecil.Mdb.dll和Unity.Cecil.Pdb.dll这三个,把他们复制到XLua\Src\Editor文件夹下。
最后再将xLua-master下的Tools文件夹整个复制到项目根目录下面,和Assets保持同级,到这里整个xlua环境就配置好了。

步骤1

新建一个场景,随便建一个物体当做玩家,然后新建脚本命名为BoxPlayer,写入以下代码

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using XLua;


[Hotfix]
public class BoxPlayer : MonoBehaviour {
    public float moveSpeed;
       void Start () {
       
    }
       
       // Update is called once per frame
       void Update () {
        PlayerMoveTest();
    }
    [LuaCallCSharp]
    private void PlayerMoveTest()
    {
        transform.Translate(transform.forward * moveSpeed * Time.deltaTime,Space.World);
    }
}

逻辑讲解

首先是using XLua,然后将这个类打上Hotfix标签,代表这个类是要打补丁的。
然后在需要打补丁的方法上打一个标签[LuaCallCSharp]。
运行场景,这个物体会向前方运动, (场景中public的moveSpeed的速度是5)
然后在场景里新建一个StreamingAssets的文件夹, 在这个文件夹下创建一个文本文档:Hotfix.lua.txt 一定要以.lua.txt结尾。

lua里面调用c#方法需要CS开头来引用unity里面的类和方法,如果不是静态方法,比如transform.TransLate(….);
在lua里不能这样直接点出来,需要冒号来引用,self.transform:Translate(…..),
比如transform.GetComponent()….在lua里也是要换成冒号,并且不能使用<>的方式来获取组件。需要通过transform : GameObject(“GameObject”)的方式来获取。
如果是静态方法,比如说Time.deltaTime,可以直接使用CS.UnityEngine的命名空间来点出来。
另外xlua.hotfix(a,’b’,c)这种写法,里面的内容分别代表:a,要更改的C#脚本的脚本名;b,要更改的这个里面的方法名,需要单引号括起来;c,要替换的lua方法

print('执行更改')
xlua.hotfix(CS.BoxPlayer,'PlayerMoveTest',function(self)
       self.transform:Translate(self.transform.right *CS.UnityEngine.Time.deltaTime *15)
       self.transform:GetComponent("MeshRenderer").material.color =CS.UnityEngine. Color.black
end)

然后新建一个脚本Hotfix脚本挂在相机上,写入以下代码:

using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
using XLua;
public class HotFixScript : MonoBehaviour {
    LuaEnv LuaEnv = new LuaEnv();
       void Start () {
        LuaEnv.AddLoader(MyLoder);
        LuaEnv.DoString("require'Hotfix'");
       }
       
       public  byte[]MyLoder(ref string file)
    {
        string path = Application.streamingAssetsPath + "/" + file + ".lua.txt";
        return System.Text.Encoding.UTF8.GetBytes(File.ReadAllText(path));
    }
    private void OnDisable()
    {
        LuaEnv.DoString("require'callback'");
    }
    private void OnDestroy()
    {
        LuaEnv.Dispose();
    }
    void Update () {
              
       }
}

逻辑讲解

首先是LuaEnv,这个是Xlua的一个入口,通过实例化它来执行操作,然后执行自己的lua文本时需要自定义Loder,来让LuaEnv根据自定义的Loder里面的路径来寻找自己创建的lua文本,否则找不到。然后在销毁这个组件时,关闭luaenv的实例化。
在Start里面LuaEnv.DoString(“require’Hotfix’”);就是执行的刚刚创建的Hotfix.lua.txt里面的代码。
这个时候点击运行场景,会发现物体的颜色变成了黑色,然后运动也不是向前运动而是向右,速度也从5变成了15。

另外,在lua更改了unity里面的方法,需要在结束运行时,取消对此方法的更改,否则会报错,更改方式就是,在OnDisable里面执行另一个lua文档,里面写一句话就可以:xlua.hotfix(CS.BoxPlayer,’PlayerMoveTest’,nil)

以上就完成了一个Xlua更改C#执行方法的演示示例。

继续学习

如果只需要更改速度,不更改其他方法,比如速度的变量moveSpeed是私有的并且在c#脚本里赋值为5 了,在lua里面可以这样写:

xlua.private_accessible(CS.BoxPlayer)
xlua.hotfix(CS.BoxPlayer,'Start',function(self)
       self.moveSpeed = 15;
end)

xlua.private_accessible(CS.BoxPlayer)就是获取指定类里的私有变量的方式,但是执行LuaEnv.DoString(“require’Hotfix’”);的方法必须放到游戏一开始的Awake里执行,因为修改的是Start,所以有这个先后顺序需要注意。
但是如果Start里面不止这一个变量,但是只需要更改某个变量时,其他不变时,岂不是要写很多代码,xlua考虑到这一点,也做了一个方式,就是引用一个lua库:uitl.lua.txt。
具体位置是在XLua\Resources\xlua文件夹下,把它复制到和自己写的lua文本一个目录下就可以了。

local util=require 'util'

xlua.private_accessible(CS.BoxPlayer)
util.hotfix_ex(CS.BoxPlayer,'Start',function(self)
       self.Start(self)
       self.moveSpeed=15
end)

这样是和上面一样的效果,重点就是local util=require ‘util’有了它才可以更改C#方法里的部分逻辑和变量。


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!