xlua的hotfixManager

文章目录

        • 前言
        • 与LuaFramework的对比
        • xlua如何打热补丁
        • xlua的加载器
        • 从本地修复
        • 从服务器端修复
          • 代码如下

前言

  • 最近要用到xlua的热更新,踩了一下坑

与LuaFramework的对比

  • 先苦后甜与先甜后苦

xlua如何打热补丁

  • 注意要在player setting里面设置Hotfix_Enable
  • 每次修改完C#代码之后都要进行HotfixInjector【热补丁注入】
  • lua代码如下
xlua.private_accessible(CS.UIScript);
xlua.hotfix(CS.UIScript, 'InitColor', function(self)
	self.mText.text = "hello world";
	self.mImage.color = CS.UnityEngine.Color.green;
	self = nil;
	end
)
print('热更新完毕~');

xlua的加载器

  • 因为要从streamingAsset文件夹中加载文件
  • xlua默认是只能从resource文件夹加载的
  • 所以创建一个加载器
 	luaEnv = new LuaEnv();
   luaEnv.AddLoader(StreamingAssetLoader);

	//streamingAssetLoader加载器
    private byte[] StreamingAssetLoader(ref string filepath)
    {
        print(filepath);
        print(Application.streamingAssetsPath);
        string absPath = Application.streamingAssetsPath + "/" + filepath + ".lua.txt";
        string content = File.ReadAllText(absPath);
        return Encoding.UTF8.GetBytes(content);
    }

从本地修复

  • 增加一个场景,在该场景里面进行修复
  • 首先从本地StreamingAssets文件夹里面获取lua文件,然后就行了
  • 即使要修复的脚本涉及多个场景,也可以覆盖
  private LuaEnv luaEnv;

    // Start is called before the first frame update
    void Start()
    {
        luaEnv = new LuaEnv();
        luaEnv.DoString("require 'Do'");
    }

从服务器端修复

  • 生成资源信息文件,包含lua文件的名与lua文件的md5,用‘|’划分
  • 在服务器获取资源信息文件,与本地的资源信息文件进行对比
  • 如果完全相同,就直接加载lua文件进行修复
  • 如果不同,就获取需要更新的lua文件名,同时用服务器的资源文件对本地的进行替换,
  • 组拼地址后从服务器下载lua文件对本地进行替换
  • 然后加载lua文件,进行热修复
代码如下
 private string webFileUrlBase = null;
    private string webFilesUrl = null;
    private string webLuaUrl = null;
    private LuaEnv luaEnv;
    private string localFilesAddress = null;
    private string[] webFiles;
    private string[] localFiles;
    private string localFilesPath = Application.streamingAssetsPath+"/files.txt";

    // Start is called before the first frame update
    void Awake()
    {

        luaEnv = new LuaEnv();
        luaEnv.AddLoader(StreamingAssetLoader);
        webFileUrlBase = "http://192.168.0.106/";
        webFilesUrl = webFileUrlBase + "Files.txt";
        localFilesAddress = "file://" + Application.streamingAssetsPath+"/files.txt";
        StartCoroutine("LoadAsset");
        
    }

    private IEnumerator LoadAsset()
    {
        #region 下载服务器端的files.txt
        WWW www = new WWW(webFilesUrl);
        yield return www;
        if (www.isDone)
        {
             webFiles = www.text.Split('|');
        }
        #endregion

        #region 加载本地的files.txt
        WWW local_www = new WWW(localFilesAddress);
        yield return local_www;
        if (local_www.isDone)
        {
            localFiles = local_www.text.Split('|');
        }
        #endregion

        //进行md5校验
        if (localFiles[1] != webFiles[1])
        {
            #region 需要更新
            Debug.Log("需要更新");

            #region 更新客户端files文件
            File.Delete(localFilesPath);
            FileStream fs = new FileStream(localFilesPath, FileMode.CreateNew);
            StreamWriter sw = new StreamWriter(fs);
            sw.WriteLine(webFiles[0].Trim() + "|" + webFiles[1].Trim());
            sw.Close();
            fs.Close();
            #endregion

            #region  下载web端的lua文件
            WWW webLua = new WWW(webFileUrlBase + webFiles[0]);
            yield return webLua;
            if (webLua.isDone)
            {
                File.Delete(Application.streamingAssetsPath + "/Do.lua.txt");
                FileStream temp = new FileStream(Application.streamingAssetsPath + "/Do.lua.txt", FileMode.CreateNew);
                StreamWriter sw2 = new StreamWriter(temp);
                sw2.Write(webLua.text);
                sw2.Close();
                temp.Close();
            }
            #endregion

            #endregion
        }

        luaEnv.DoString("require 'Do'");
        yield return new WaitForSeconds(2);
        SceneManager.LoadScene("SampleScene");
    }

    //streamingAssetLoader加载器
    private byte[] StreamingAssetLoader(ref string filepath)
    {
        print(filepath);
        print(Application.streamingAssetsPath);
        string absPath = Application.streamingAssetsPath + "/" + filepath + ".lua.txt";
        string content = File.ReadAllText(absPath);
        return Encoding.UTF8.GetBytes(content);
    }

你可能感兴趣的:(Unity)