XLua学习 热更新步骤整理

前言

使用Xlua可以用lua语言覆盖CS脚本的内容。
这里贴出官方的热更新教程~
https://github.com/Tencent/xLua/blob/master/Assets/XLua/Doc/hotfix.md
然后以下是本文大致的实现步骤:
1. 这里使用AB包把需要修改的物体对象资源、要覆盖CS脚本的lua文件打包
2. 客户端从服务器下载ab包,然后把新ab包缓存在本地,直到服务器下一次更新ab包
3. 然后客户端用以前写好的CS脚本来从ab包获取lua文本,放到本地沙盒路径,然后再执行lua文本内容
4. lua文本里可以继续从ab包缓存里获取其他资源,并对原CS脚本进行覆盖来修改bug

准备

准备阶段,也就是正常的用C#编码阶段,也可以说是作预处理阶段,发布游戏之前,下次客户端更新之前。
设置HotFix
设置[LuaCallSharp]
1. 在需要更新的类上加上[Hotfix] ,这个类需要提前预判,一般来说只更新UI部分,一般不更新物体,数据类
2. 在可能更新的类方法中前[LuaCallCsharp]
如:

[Hotfix]
public class BeHotFixA : MonoBehaviour {
    public int num1 = 100;
    private int num2 = 200;
    [LuaCallCSharp]
    void Update () {
        if (Input.GetMouseButtonDown (0)) {
            GameObject go = Resources.Load ("ObjA") as GameObject;
            Instantiate (go);
        }
    }
}

注意:这里第三步骤的脚本也是发布游戏之前写好的脚本

一、本地功能的逻辑实现

现在就进入处理阶段了,此时出现bug,需要做热更新了
如下就是要替代C#的Lua代码,通过xlua.hotfix()方法

--第二次开发-》开始使用lua更新原工程内容
--BeHotFixA类的私有成员可以被访问
xlua.private_accessible(CS.BeHotFixA)
--替换CS中某个类的某个方法
xlua.hotfix(CS.BeHotFixA,"Update",function(self)
    print(num1,num2)
    local cs = CS.UnityEngine
    if cs.Input.GetMouseButtonDown(0) then
        local ab = cs.GameObject.Find("GameObject"):GetComponent("DownLoadAB").ab
        local obj = ab:LoadAsset("ObjB")
        local go = cs.GameObject.Instantiate(obj)
    end
end)
二、把资源进行打包

当发生bug,就需要把替代C#的lua文件,要更改的UI、材质等资源
做成AssetBundle包

三、AB包放到服务器

第三步应该是提前准备阶段就做好的,因为这里是在本机测试,实际放到服务器,直接更改路径即可

public class DownLoadABB : MonoBehaviour {
    private string path = "file:///Users/neworigin/Desktop/YoungAB/ab";
    public AssetBundle ab;
    void Awake(){
        WWW www = WWW.LoadFromCacheOrDownload (path, 11);//三
        ab  = www.assetBundle;//四
        TextAsset hot = ab.LoadAsset ("hot.lua.txt") as TextAsset;
        Debug.Log (hot.text);//五
        string newPath = Application.persistentDataPath + "/hot.lua.txt";
        Debug.Log (newPath);
        //把AB里面的Hot脚本内容写入到沙盒路文件中
        File.WriteAllText(newPath,hot.text);//五、六
    }
四、下载新AB资源

使用WWW 下载AB包,然后获取ab包的资源(lua)和其他要覆盖资源

五、本地和服务器进行检测是否需要重新下载内容

执行游戏时,会默认调用原先做好的CS脚本,此时客户端就会从服务器获取文件,需要进行测试

六、执行下从服务器(AB包里)下载到本地的lua文件

此CS脚本需要在发布游戏前写好,做预处理。当出现问题时,就可以从(这里是沙盒路径)本地路径
找到lua来执行。 这里的lua就是重新从服务器下载好的lua文本

public class HotFix : MonoBehaviour {
    void Awake(){
        LuaBehaviour.luaEnv.AddLoader (MyLoader);   
        LuaBehaviour.luaEnv.DoString ("require 'hot'");
    }

    public byte[] MyLoader(ref string filepath) {
        string path = Application.persistentDataPath + "/" + filepath + ".lua.txt";
        string str = File.ReadAllText (path);
        return System.Text.Encoding.UTF8.GetBytes (str);
    }
}

另外补充下对AddLoader 和 MyLoader 的理解

AddLoader()参数是方法名,这个方法的类型是被定义好的委托类型,
filepath是DoString下的require ‘hot’ 的 hot 名
此时就根据hot名配合沙盒路径找到那个lua文件
lua文件被流读出来,用字符串的形式读出,最后返回出来全部内容 被DoString() 全部执行

DoString(“print(‘如这样的形式’)”)

七、执行Lua更新内容、Lua中就是要hotfix来完成原CS中代码的替换

就是执行Xlua的Dostring,来执行新写好的lua文本内容

LuaBehaviour.luaEnv.DoString ("require 'hot'");
八、在下一次发布版本时,把Lua内容替换成CS内容

以上就热更新完成了,当下一次版本发布时,就把原来的lua文件覆盖的CS的bug重构修复即可

这里注意

每次Build 新的ab包后,服务器加载也要更新,因为有缓存,要设置新版本号来提示客户端重新下载
如:WWW www = WWW.LoadFromCacheOrDownload (path, 11)
且版本号要从小到大加的。
每次CS脚本更新之后,就要重新生成GenerateXlua一下,然后点Hotfix injext in Enditor一下。才能播放测试。

Lua文本因为没有IDE提示,很容易写错(字符错误),建议在之前先用Resource.Load直接获取Lua文本(不build ab包,不从服务器下载) 直接获取lua内容来进行测试,直到lua文本不报错再换回来。

你可能感兴趣的:(XLua)