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

Xlua更新

[复制链接]
发表于 2021-8-14 15:06 | 显示全部楼层 |阅读模式
这里贴出官方的热更新教程~
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]
如:
  1. [Hotfix]
  2. public class BeHotFixA : MonoBehaviour {
  3.     public int num1 = 100;
  4.     private int num2 = 200;
  5.     [LuaCallCSharp]
  6.     void Update () {
  7.         if (Input.GetMouseButtonDown (0)) {
  8.             GameObject go = Resources.Load ("ObjA") as GameObject;
  9.             Instantiate (go);
  10.         }
  11.     }
  12. }
复制代码
注意:这里第三步骤的脚本也是发布游戏之前写好的脚本
一、本地功能的逻辑实现
现在就进入处理阶段了,此时出现bug,需要做热更新了
如下就是要替代C#的Lua代码,通过xlua.hotfix()方法
  1. --第二次开发-》开始使用lua更新原工程内容
  2. --BeHotFixA类的私有成员可以被访问
  3. xlua.private_accessible(CS.BeHotFixA)
  4. --替换CS中某个类的某个方法
  5. xlua.hotfix(CS.BeHotFixA,"Update",function(self)
  6.     print(num1,num2)
  7.     local cs = CS.UnityEngine
  8.     if cs.Input.GetMouseButtonDown(0) then
  9.         local ab = cs.GameObject.Find("GameObject"):GetComponent("DownLoadAB").ab
  10.         local obj = ab:LoadAsset("ObjB")
  11.         local go = cs.GameObject.Instantiate(obj)
  12.     end
  13. end)
复制代码
二、把资源进行打包
当发生bug,就需要把替代C#的lua文件,要更改的UI、材质等资源
做成AssetBundle包
三、AB包放到服务器
第三步应该是提前准备阶段就做好的,因为这里是在本机测试,实际放到服务器,直接更改路径即可
  1. public class DownLoadABB : MonoBehaviour {
  2.     private string path = "file:///Users/neworigin/Desktop/YoungAB/ab";
  3.     public AssetBundle ab;
  4.     void Awake(){
  5.         WWW www = WWW.LoadFromCacheOrDownload (path, 11);//三
  6.         ab  = www.assetBundle;//四
  7.         TextAsset hot = ab.LoadAsset ("hot.lua.txt") as TextAsset;
  8.         Debug.Log (hot.text);//五
  9.         string newPath = Application.persistentDataPath + "/hot.lua.txt";
  10.         Debug.Log (newPath);
  11.         //把AB里面的Hot脚本内容写入到沙盒路文件中
  12.         File.WriteAllText(newPath,hot.text);//五、六
  13.     }
复制代码
四、下载新AB资源
使用WWW 下载AB包,然后获取ab包的资源(lua)和其他要覆盖资源
五、本地和服务器进行检测是否需要重新下载内容
执行游戏时,会默认调用原先做好的CS脚本,此时客户端就会从服务器获取文件,需要进行测试
六、执行下从服务器(AB包里)下载到本地的lua文件
此CS脚本需要在发布游戏前写好,做预处理。当出现问题时,就可以从(这里是沙盒路径)本地路径
找到lua来执行。 这里的lua就是重新从服务器下载好的lua文本
  1. public class HotFix : MonoBehaviour {
  2.     void Awake(){
  3.         LuaBehaviour.luaEnv.AddLoader (MyLoader);   
  4.         LuaBehaviour.luaEnv.DoString ("require 'hot'");
  5.     }
  6.     public byte[] MyLoader(ref string filepath) {
  7.         string path = Application.persistentDataPath + "/" + filepath + ".lua.txt";
  8.         string str = File.ReadAllText (path);
  9.         return System.Text.Encoding.UTF8.GetBytes (str);
  10.     }
  11. }
复制代码
另外补充下对AddLoader 和 MyLoader 的理解
AddLoader()参数是方法名,这个方法的类型是被定义好的委托类型,
filepath是DoString下的require ‘hot’ 的 hot 名
此时就根据hot名配合沙盒路径找到那个lua文件
lua文件被流读出来,用字符串的形式读出,最后返回出来全部内容 被DoString() 全部执行
DoString(“print(‘如这样的形式’)”)
七、执行Lua更新内容、Lua中就是要hotfix来完成原CS中代码的替换
就是执行Xlua的Dostring,来执行新写好的lua文本内容
  1. 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文本不报错再换回来
懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2024-11-24 11:22 , Processed in 0.121291 second(s), 25 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

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