|
这里贴出官方的热更新教程~
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文本不报错再换回来 |
|