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

使用XLua实现简单热更新

[复制链接]
发表于 2023-4-9 11:27 | 显示全部楼层 |阅读模式
使用XLua热更新

简单的XLua热更Demo
1.首先第一步,是下载xlua插件,可以直接在GitHub下载:xlua插件地址
2.按照热更新设置:在Project Setting 的Player的Scripting Define Symbols添加HOTFIX_ENABLE,这样在编辑器上会看到XLua,然后有Generate Code和HotFix Inject In Editor,在C#脚本有改动的时候就要Generate Code一下(会提示finish)
3.要热更的地方需要标识[Hotfix]特性,在类声明的位置标识的时候在打包的时候会热更不成功,解决方案:
  1. publicstaticclassHotFixConfig{[Hotfix]publicstaticList<Type> by_field =newList<Type>(){typeof(Load),typeof(Cube)};}
复制代码
4.要执行lua,开启一个lua虚拟机
  1. privatevoidAwake(){
  2.         luaEnv =newLuaEnv();
  3.         luaEnv.AddLoader(MyLoader);
  4.         luaEnv.DoString("require 'Test'");}privatebyte[]MyLoader(refstring filePath){string absPath =@"E:\Unity3d\HotFix\XluaTest" + filePath + ".lua.txt";return  System.Text.Encoding.UTF8.GetBytes(File.ReadAllText(absPath));}
复制代码
5.lua那边要调用的C#函数要标识为[LuaCallCSharp]
这里只实现了简单的下载单个资源,具体需要再去细写
  1. [LuaCallCSharp]publicvoidLoadResource(string resName,string filePath){StartCoroutine(Load(resName, filePath));}IEnumeratorLoad(string resName,string filePath){AssetBundle assetBundle=null;if(!bundleDic.ContainsKey(filePath)){UnityWebRequest request = UnityWebRequestAssetBundle.GetAssetBundle(@"path"+ filePath);yieldreturn request.SendWebRequest();
  2.             Debug.Log(request);
  3.             bundleDic.Add(filePath, DownloadHandlerAssetBundle.GetContent(request));}yieldreturn bundleDic[filePath];
  4.         assetBundle = bundleDic[filePath];//.downloadHandler as DownloadHandlerAssetBundle).assetBundle;
  5.         Debug.Log(assetBundle);//WWW wWW = new WWW(@"path" + filePath);//yield return wWW;//AssetBundle assetBundle = wWW.assetBundle;//Debug.Log(assetBundle);GameObject obj = assetBundle.LoadAsset<GameObject>(resName);if(!objDic.ContainsKey(resName)){
  6.             objDic.Add(resName, obj);}}[LuaCallCSharp]publicGameObjectGetPrefab(string resName){return objDic[resName];}
复制代码
这里打包AssetBundle用的是官方的插件,也是可以在GitHub下载的:AssetBundle插件地址
附:导入方式:Window-》Package Manager-》右上角的加号-》选择第一个(Add package from disk)->找到下载的这个文件的package.json文件
6.开启了lua虚拟机,当然也要销毁
  1. privatevoidOnDestroy(){
  2.         luaEnv.Dispose();}
复制代码
  1. privatevoidOnDisable(){
  2.        luaEnv.DoString("require 'LuaDispose'");}//LuaDispose.lua.txt内容
  3.     xlua.hotfix(CS.Cube,"Update",nil)
  4.     xlua.hotfix(CS.Load,"Start",nil)
  5.     xlua.hotfix(CS.Load,"Update",nil)
复制代码
8.其他脚本
  1. publicclassLoad:MonoBehaviour{publicHotFixScript hotFix;privatevoidAwake(){if(!hotFix){
  2.             hotFix =GetComponent<HotFixScript>();}}[LuaCallCSharp]publicvoidStart(){}[LuaCallCSharp]publicvoidUpdate(){}}publicclassCube:MonoBehaviour{publicRigidbody rigidbody1;// Start is called before the first frame updatevoidStart(){
  3.         rigidbody1 = gameObject.GetComponent<Rigidbody>();}[LuaCallCSharp]// Update is called once per framepublicvoidUpdate(){if(Input.GetKeyDown(KeyCode.W)){
  4.             rigidbody1.AddForce(Vector3.up*300);}}}
复制代码
9.lua热更内容
  1. local UnityEngine=CS.UnityEngine
  2. xlua.hotfix(CS.Cube,'Update',function(self)if(UnityEngine.Input.GetKeyDown(UnityEngine.KeyCode.G))then
  3.         self.rigidbody1:AddForce(UnityEngine.Vector3.up*300)endend)
  4. xlua.hotfix(CS.Load,'Start',function(self)
  5.     self.hotFix:LoadResource('Sphere','gameobject.unity3d')end)
  6. xlua.hotfix(CS.Load,'Update',function(self)if(UnityEngine.Input.GetKeyDown(UnityEngine.KeyCode.T))thenlocal obj= UnityEngine.GameObject.Instantiate(self.hotFix:GetPrefab('Sphere'))
  7.        obj.transform.position=UnityEngine.Vector3.right
  8.     endend)
复制代码
10.在Loading场景加载那两个lua文件
  1. publicclassLoadScene:MonoBehaviour{// Start is called before the first frame updatevoidStart(){StartCoroutine(LoadLuaTxt());}IEnumeratorLoadLuaTxt(){UnityWebRequest request = UnityWebRequest.Get(@"path/Test.lua.txt");yieldreturn request.SendWebRequest();string str = request.downloadHandler.text;
  2.         File.WriteAllText(@"E:\Unity3d\HotFix\XluaTest"+"Test.lua.txt",str);UnityWebRequest request1 = UnityWebRequest.Get(@"path/LuaDispose.lua.txt");yieldreturn request1.SendWebRequest();string str1 = request1.downloadHandler.text;
  3.         File.WriteAllText(@"E:\Unity3d\HotFix\XluaTest" + "LuaDispose.lua.txt", str1);
  4.         SceneManager.LoadSceneAsync("SampleScene");}}
复制代码
附:path都是指的服务器地址,之前有需求用了腾讯云的对象存储,所以博主这里都是放在腾讯云里的
11.其他:从服务器下载图片资源方法
  1. IEnumeratorLoadImage(){UnityWebRequest request = UnityWebRequestTexture.GetTexture(@"path/AssetBundles/PC/1.jpg");yieldreturn request.SendWebRequest();if(request.error !=null){
  2.             Debug.Log(request.error);}Texture2D texture2D = DownloadHandlerTexture.GetContent(request);
  3.         image.sprite = Sprite.Create(texture2D,newRect(0,0,texture2D.width,texture2D.height),Vector2.zero);}
复制代码
懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2024-6-4 03:16 , Processed in 0.094430 second(s), 25 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

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