APSchmidt 发表于 2023-4-9 11:27

使用XLua实现简单热更新

使用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.要热更的地方需要标识特性,在类声明的位置标识的时候在打包的时候会热更不成功,解决方案:
publicstaticclassHotFixConfig{publicstaticList<Type> by_field =newList<Type>(){typeof(Load),typeof(Cube)};}4.要执行lua,开启一个lua虚拟机
privatevoidAwake(){
      luaEnv =newLuaEnv();
      luaEnv.AddLoader(MyLoader);
      luaEnv.DoString("require 'Test'");}privatebyte[]MyLoader(refstring filePath){string absPath =@"E:\Unity3d\HotFix\XluaTest\" + filePath + ".lua.txt";returnSystem.Text.Encoding.UTF8.GetBytes(File.ReadAllText(absPath));}5.lua那边要调用的C#函数要标识为[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();
            Debug.Log(request);
            bundleDic.Add(filePath, DownloadHandlerAssetBundle.GetContent(request));}yieldreturn bundleDic;
      assetBundle = bundleDic;//.downloadHandler as DownloadHandlerAssetBundle).assetBundle;
      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)){
            objDic.Add(resName, obj);}}publicGameObjectGetPrefab(string resName){return objDic;}这里打包AssetBundle用的是官方的插件,也是可以在GitHub下载的:AssetBundle插件地址
附:导入方式:Window-》Package Manager-》右上角的加号-》选择第一个(Add package from disk)->找到下载的这个文件的package.json文件
6.开启了lua虚拟机,当然也要销毁
privatevoidOnDestroy(){
      luaEnv.Dispose();}privatevoidOnDisable(){
       luaEnv.DoString("require 'LuaDispose'");}//LuaDispose.lua.txt内容
    xlua.hotfix(CS.Cube,"Update",nil)
    xlua.hotfix(CS.Load,"Start",nil)
    xlua.hotfix(CS.Load,"Update",nil)8.其他脚本
publicclassLoad:MonoBehaviour{publicHotFixScript hotFix;privatevoidAwake(){if(!hotFix){
            hotFix =GetComponent<HotFixScript>();}}publicvoidStart(){}publicvoidUpdate(){}}publicclassCube:MonoBehaviour{publicRigidbody rigidbody1;// Start is called before the first frame updatevoidStart(){
      rigidbody1 = gameObject.GetComponent<Rigidbody>();}// Update is called once per framepublicvoidUpdate(){if(Input.GetKeyDown(KeyCode.W)){
            rigidbody1.AddForce(Vector3.up*300);}}}9.lua热更内容
local UnityEngine=CS.UnityEngine

xlua.hotfix(CS.Cube,'Update',function(self)if(UnityEngine.Input.GetKeyDown(UnityEngine.KeyCode.G))then
      self.rigidbody1:AddForce(UnityEngine.Vector3.up*300)endend)

xlua.hotfix(CS.Load,'Start',function(self)
    self.hotFix:LoadResource('Sphere','gameobject.unity3d')end)

xlua.hotfix(CS.Load,'Update',function(self)if(UnityEngine.Input.GetKeyDown(UnityEngine.KeyCode.T))thenlocal obj= UnityEngine.GameObject.Instantiate(self.hotFix:GetPrefab('Sphere'))
       obj.transform.position=UnityEngine.Vector3.right
    endend)10.在Loading场景加载那两个lua文件
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;
      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;
      File.WriteAllText(@"E:\Unity3d\HotFix\XluaTest\" + "LuaDispose.lua.txt", str1);
      SceneManager.LoadSceneAsync("SampleScene");}}附:path都是指的服务器地址,之前有需求用了腾讯云的对象存储,所以博主这里都是放在腾讯云里的
11.其他:从服务器下载图片资源方法
IEnumeratorLoadImage(){UnityWebRequest request = UnityWebRequestTexture.GetTexture(@"path/AssetBundles/PC/1.jpg");yieldreturn request.SendWebRequest();if(request.error !=null){
            Debug.Log(request.error);}Texture2D texture2D = DownloadHandlerTexture.GetContent(request);
      image.sprite = Sprite.Create(texture2D,newRect(0,0,texture2D.width,texture2D.height),Vector2.zero);}
页: [1]
查看完整版本: 使用XLua实现简单热更新