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

Unity笔记之xLua热更新

[复制链接]
发表于 2023-4-11 18:37 | 显示全部楼层 |阅读模式
需求:实现热更新全流程。(代码热更、物体热更)

本篇文章使用的是xlua来开发的。学习的是这位老哥的
步骤:
1:导入xlua

(1)首先xlua直接去hub上下过来(XLua)。


(2)解压压缩包。打开文件夹,把Assets里面的东西全部复制到自己工程的Assets文件夹下。



这里面的其他文件夹是我自己创建的。
然后再把tools也拖到工程目录里面跟Assets同级。


到这里,xlua环境就算弄好了(不学习、运行案例的话)。
下面就是官方案例运行了:
案例都在XLua下的Examples文件夹里面。
运行案例之前需要打开场景之后;
在菜单面板找到并点击XLua——Generate Code(生成);
然后点击Hotfix Inject In Editor(注入unity编辑器,这样才能在unity编辑器里面运行成功);
最后就是点击运行就可以了。
2:搭建自己的游戏场景并写入逻辑

(1)新建一个场景取名Game并放到Scenes文件夹下。
(2)在Game场景里面创建一个Plane作为地板,创建一个Cube作为游戏物体。
(3)给Cube添加刚体组件(Rigidbody)和脚本控制(Cube.cs)
  1. usingSystem.Collections;usingSystem.Collections.Generic;usingUnityEngine;usingXLua;[Hotfix]//标识publicclassCube:MonoBehaviour{privateRigidbody _rigidbody;//定义组件voidStart(){
  2.         _rigidbody =GetComponent<Rigidbody>();//获取组件}[LuaCallCSharp]//标识voidUpdate(){if(Input.GetKeyDown(KeyCode.W))//控制{
  3.             _rigidbody.AddForce(Vector3.up *500);}}}
复制代码
(4)在工程文件的同一层级创建一个Lua文件夹,并在Lua文件夹下创建两个文本文件(取名Test.lua.txt和LuaDispose.lua.txt)
输入内容
Test.lua.txt 的内容
  1. local UnityEngine=CS.UnityEngine
  2. xlua.hotfix(CS.Cube,'Update',function(self)if(UnityEngine.Input.GetKeyDown(UnityEngine.KeyCode.S))then
  3.     self._rigidbody:AddForce(UnityEngine.Vector3.up*500)endend)
复制代码
LuaDispose.lua.txt 的内容
  1. xlua.hotfix(CS.Cube,'Update',nil)
复制代码
(5)创建一个热更脚本(HotfixScript.cs)并在场景中创建一个空物体取名HotfixScript,把脚本拖到空物体上。
  1. usingSystem.Collections;usingSystem.Collections.Generic;usingSystem.IO;usingSystem.Text;usingUnityEngine;usingUnityEngine.Networking;usingXLua;publicclassHotFixScript:MonoBehaviour{privateLuaEnv _luaEnv;//创建lua运行环境privatevoidAwake(){
  2.         _luaEnv =newLuaEnv();//实例lua运行环境
  3.         _luaEnv.AddLoader(MyLoader);//必须要有的
  4.         _luaEnv.DoString("require'Test'");//loader进行加载Test.lua.txt  从"E:\Test\Lua" + filePath + ".lua.txt"文件中进行加载 (注:require是固定不变的,调用完才能取得里面的变量)}privatebyte[]MyLoader(refstring filePath){string absPath =@"F:\XLua\Lua" + filePath + ".lua.txt";return Encoding.UTF8.GetBytes(File.ReadAllText(absPath));}voidStart(){}voidUpdate(){}privatevoidOnDisable(){
  5.         _luaEnv.DoString("require'LuaDispose'");//执行LuaDispose里面的关闭方法}privatevoidOnDestroy(){
  6.         _luaEnv.Dispose();//释放lua环境}}
复制代码
然后就可以生成——注入——运行了。(到这里第一个补丁就完成了)
3:创建热更资源并打出AB包

打ab包我之前的一篇博客里面有三种方法,随便选一种即可。
这里我用的是AssetBundle Browser打包的。
打出ab包之后全选复制到服务器文件夹下的AssetBundles文件夹里面(我打的有两个物体)



4:搭建一个简单的本地服务器

本地服务器我有一篇博客也写到过。
这里我用的是NetBox2的方法。
5:从服务器上下载AssetBundles,并加载出来

HotFixScript.cs脚本内容更新一下从服务器上下载AssetBundles,并加载出来的内容。
  1. usingSystem.Collections;usingSystem.Collections.Generic;usingSystem.IO;usingSystem.Text;usingUnityEngine;usingUnityEngine.Networking;usingXLua;publicclassHotFixScript:MonoBehaviour{privateLuaEnv _luaEnv;//创建lua运行环境privatevoidAwake(){
  2.         _luaEnv =newLuaEnv();//实例lua运行环境
  3.         _luaEnv.AddLoader(MyLoader);//必须要有的
  4.         _luaEnv.DoString("require'Test'");//loader进行加载Test.lua.txt  从"E:\Test\Lua" + filePath + ".lua.txt"文件中进行加载 (注:require是固定不变的,调用完才能取得里面的变量)}privatebyte[]MyLoader(refstring filePath){string absPath =@"F:\XLua\Lua" + filePath + ".lua.txt";return Encoding.UTF8.GetBytes(File.ReadAllText(absPath));}voidStart(){}voidUpdate(){}privatevoidOnDisable(){
  5.         _luaEnv.DoString("require'LuaDispose'");//执行LuaDispose里面的关闭方法}privatevoidOnDestroy(){
  6.         _luaEnv.Dispose();//释放lua环境}[LuaCallCSharp]//需要热更脚本里面调用的方法必须加上这个标签publicvoidLoadResource(string resName,string filePath)//开启加载assetbundle里面的资源的协程{StartCoroutine(Load(resName, filePath));}privateDictionary<string, GameObject> _objectsAssetBundleDic =newDictionary<string, GameObject>();//把加载出来的AssetBundle物体存起来,方便使用的时候调用privatestring serverPath =@"http://localhost/AssetBundles";//服务器AssetBundles存放地址IEnumeratorLoad(string resName,string filePath)//加载assetbundle里面的资源{UnityWebRequest request = UnityWebRequestAssetBundle.GetAssetBundle(serverPath + filePath);yieldreturn request.SendWebRequest();AssetBundle ab =(request.downloadHandler asDownloadHandlerAssetBundle).assetBundle;GameObject go = ab.LoadAsset<GameObject>(resName);
  7.         Debug.Log(go.name);
  8.         _objectsAssetBundleDic.Add(resName, go);}[LuaCallCSharp]//需要热更脚本里面调用的方法必须加上这个标签publicGameObjectGetAssetBundlePrefab(string resName)//获取到AssetBundle物体{return _objectsAssetBundleDic[resName];}}
复制代码
创建一个热更加载代码(Load.cs),以便通过lua调用C#里面的方法。
  1. usingSystem;usingUnityEngine;usingXLua;[Hotfix]publicclassLoad:MonoBehaviour{publicHotFixScript hot;//定义HotFixScript脚本privatevoidStart(){}privatevoidUpdate(){}}
复制代码
然后更新一下Test.lua.txt 和 LuaDispose.lua.txt 的内容
Test.lua.txt
  1. local UnityEngine=CS.UnityEngine
  2. xlua.hotfix(CS.Cube,'Update',function(self)if(UnityEngine.Input.GetKeyDown(UnityEngine.KeyCode.S))then
  3.     self._rigidbody:AddForce(UnityEngine.Vector3.up*500)--(Lua里面调用静态方法直接”.“就可以了,非静态方法得用”:“)endend)
  4. xlua.hotfix(CS.Load,'Start',function(self)--重写Load代码里面的Start方法
  5.     self.hot:LoadResource('capsule','\\capsule')--加载ab包里面的capsule
  6. self.hot:LoadResource('sphere','\\sphere')--加载ab包里面的sphereend)
  7. xlua.hotfix(CS.Load,'Update',function(self)--重写Load代码里面的Update方法if(UnityEngine.Input.GetKeyDown(UnityEngine.KeyCode.G))then
  8.         UnityEngine.Object.Instantiate( self.hot:GetAssetBundlePrefab('capsule'))--生成capsule
  9.         UnityEngine.Object.Instantiate( self.hot:GetAssetBundlePrefab('sphere'))--生成sphereendend)
复制代码
LuaDispose.lua.txt
  1. xlua.hotfix(CS.Cube,'Update',nil)
  2. xlua.hotfix(CS.Load,'Update',nil)
  3. xlua.hotfix(CS.Load,'Start',nil)
复制代码
然后开启服务器,运行就可以了。
6:下载Lua并加载

(1)创建一个Init场景作为加下载Lua文件、配置文件的过渡场景。
(2)创建一个脚本实现Lua文件下载(LoadLua.cs)
  1. usingSystem.Collections;usingSystem.Collections.Generic;usingSystem.IO;usingUnityEngine;usingUnityEngine.Networking;usingUnityEngine.SceneManagement;publicclassLoadLua:MonoBehaviour{voidStart(){StartCoroutine(Load());}publicList<string> luaName =newList<string>();//所有需要热更的lua的名字privatestring severPath =@"http://localhost/";//服务器地址privatestring clientPath =@"F:\XLua\Lua"; //客户端lua保存地址
  2.     IEnumerator Load()//从服务器上下载热更脚本(如果有变则下载新的,没变则不下载)
  3.     {
  4.         for (int i = 0; i < luaName.Count; i++)
  5.         {
  6.             UnityWebRequest requset = UnityWebRequest.Get(severPath + luaName[i] + ".lua.txt");yieldreturn requset.SendWebRequest();string str = requset.downloadHandler.text;//获取lua的内容
  7.             Debug.Log(str);
  8.             File.WriteAllText(clientPath + luaName[i]+".lua.txt", str);//写入并存入本地}
  9.         SceneManager.LoadScene(1);//下载完跳转到游戏场景(Game)}}
复制代码
以上就是xLua热更新的整个流程了。
本文仅作为个人纪录,如有问题请自行去bilibili上看教程。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2024-5-5 12:29 , Processed in 0.145218 second(s), 26 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

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