XLua资源热更、代码热补丁DEMO

(一)导入热补丁资源和工具
xlua源代码中assets文件夹中的plugins文件夹和xlua文件夹,放到unity工程中的asset目录下,xlua中的tools文件夹,放在项目的asset目录的同级目录下。
然后配置playersetting,最后编辑器会出现热补丁注入的选项,如图所示
在这里插入图片描述
在这里插入图片描述
(二)资源热更,代码热补丁的原理和流程,步骤
步骤:
1.做一个客户端demo
2.服务器放上要更换的资源
3.客户端下载服务器要更新的资源
4.客户端使用服务端的更新资源
5.代码热补丁,实现demo中不同的功能

(三)具体实现
(1)客户端demo
功能:点击鼠标左键,生成一个cube
c#代码

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

[Hotfix]//这个类能打热补丁的意思
public class Game : MonoBehaviour
{
	private int num1=100;
	public int num3=300;
    // Start is called before the first frame update
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
        if (Input.GetMouseButtonDown(0))
        {
            //这块加载的资源,还有代码具体操作可能更改
            GameObject prefab =(GameObject) Resources.Load("Cube");
            GameObject go=Instantiate(prefab);
        }
    }
}

(2)准备热更的资源包
更改需求:把生成的cube改成球体,sphere
步骤:
1.准备好球体,准备好lua脚本,都打包成同一个ab包,如图所示在这里插入图片描述
在这里插入图片描述
2.编写脚本生成ab包
具体步骤参考本人这篇:
超详细的ab打包过程
c#代码


using UnityEditor;
using System.IO;

public class HotFixABTools : Editor
{
    [MenuItem("Tools/HotFixABCreate")]
    static void CreateHotFixAB()
    {
        //把打包资源放到这个文件夹中,没有就创建
        string path = "HotFixAssetBundles";
        if (!Directory.Exists(path))
        {
            Directory.CreateDirectory(path);
        }
        BuildPipeline.BuildAssetBundles(path, BuildAssetBundleOptions.None, BuildTarget.StandaloneOSX);
        Debug.Log("打包成功");
    }       
}

编译后,生成的包如图所示
在这里插入图片描述
(3)编写下载ab包的代码,把资源和lua脚本下载下来
具体步骤参考本人这篇:
超详细的ab打包过程
将c#代码绑到空物体上
科普路径
这个路径Application.persistentDataPath,热更的重要路径,该文件夹可读可写,在移动端唯一一个可读写操作的文件夹。

移动端可以将本地的资源(资源MD5值配置表)等一些文件放到StreamingAssets文件夹下,通过Copy到persistentDataPath下与服务器的版本文件配置表作比对,完成资源的热更。

为什么不在StreamingAsset文件夹下直接操作?因为该文件夹只读,不可写,资源无法更新进去。

为什么不在persistentDataPath文件夹操作,因为该文件夹是apk安装以后,才会形成的一个文件夹,无法提前创建。

本来以为,persistentDataPath文件夹,是每次打开游戏,形成的,里面的数据是只在打开游戏期间临时保存,关闭游戏就会消除,今天做个小测试,原来该文件夹是安装完apk以后形成,里面的数据持久存在。

c#代码

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.IO;

public class LoadHotFixAB : MonoBehaviour
{
    //这里的文件的路径名要注意
    string path = @"file:///Users/Magician/Desktop/LittleSomethingsTest/HotFixAssetBundles/hotfixab.u3d";
    public AssetBundle hotab;//把这个下载的ab包变成公共变量,别处好用
    private void Awake()
    {
        StartCoroutine(LoadHotFixABS());
    }

    IEnumerator LoadHotFixABS()
    {
        //可以先清除下缓存,一面加载了之前的
        Caching.ClearCache();
        //用有缓存机制的加载,设置版本号为1
        WWW w1 = WWW.LoadFromCacheOrDownload(path, 1);
        //拿到加载好的资源包
        hotab = w1.assetBundle;
        //资源包里的lua脚本可以用textasset读出来
        TextAsset hotlua = hotab.LoadAsset<TextAsset>("HotFixLua.lua");
        //移动端热更路径,文章中有科普
        string newPath = Application.persistentDataPath + @"/HotFixLua.lua.txt";
        //如果不存在这个路径就创建,然后讲文件写入该路径
        if (!File.Exists(newPath))
        {
            File.Create(newPath);
        }
        File.WriteAllText(newPath, hotlua.text);
        yield return null;
    }
}


(4)执行下载的lua代码,设置执行顺序
空物体挂的脚本如图所示
在这里插入图片描述
有加载ab包的,有执行lua脚本的,所以要有个执行顺序,需要设置。
在这里插入图片描述
设置成先下载包,再执行lua脚本
c#代码

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

public class Excutelua : MonoBehaviour
{
    private void Awake()
    {
        LuaEnv luaEnv = new LuaEnv();
        luaEnv.AddLoader(myLoader);
        luaEnv.DoString("require 'HotFixLua'");
        //这两句的关系是,根据这个dostring中的hotfixlua,传给了myloader里的filepath
        //所以加载器加载这个文件。
    }

    //自定以加载器
    public byte[] myLoader(ref string filepath)
    {
        //去这个路径下,把文本内容读出来,以字节数组的方式返回
        string newpath = Application.persistentDataPath + @"/" + filepath + ".lua.txt";
        string txtstring = File.ReadAllText(newpath);
        return System.Text.Encoding.UTF8.GetBytes(txtstring);
    }
}

ps:也就是说走完这一步,从打包资源和代码,到下载使用lua代码,都实现了,下面就是具体操作lua脚本进行热补丁了。
(5)热补丁代码的实现
总的目标是用lua中的update替换掉,c#的这个update,使原来点击生成cube,现在点击生成球体,并赋值坐标5,5,5
注意:修改了lua脚本,要重新打包到原来的那个目录
lua脚本

--打印版本号
print("version:0.1")
--这句表示这个类里的私有内容是可用的,前提是这个类打了热补丁标签
xlua.private_accessible(CS.Game)
--这句的意思是把这个类的update方法,用这个匿名方法替换掉
xlua.hotfix(CS.Game,"Update",
    function(self)
        --打印下Game类的私有变量和公共变量
        print(self.num1,self.num3)
        --最终把cube替换ab资源包里的球体
        local cc=CS.UnityEngine --把命名空间变成变量
        if cc.Input.GetMouseButtonDown(0) then
            --找到挂着加载ab包脚本的游戏物体
            local dGo=cc.GameObject.Find("ScriptsManager")
            --获得ab包
            local t=dGo:GetComponent("LoadHotFixAB").hotab
            --找到ab包里的资源
            local obj=t:LoadAsset("Sphere")
            --实例化这个球体
            local go=cc.GameObject.Instantiate(obj)
            --更改其位置
            go.transform.position=cc.Vector3(5,5,5)
        end

    end
)

重新打包,运行会报这个错,这个错表示lua热补丁没注入进去
在这里插入图片描述
这个错的解决方案:
先点击这个
在这里插入图片描述
再点击这个
在这里插入图片描述
就能热补丁注入成功了,记住,只要是更改了脚本或者资源,重新打包后,都要重新生成lua代码,然后再注入
科普一下,this,self,指的是脚本依附的这个游戏对象

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值