Unity Addressables热更流程

news/2024/12/2 18:01:06/

一、分组(网上教程一大堆)

二、构建

        构建前设置:

                1、分组设置。所有组做远端构建加载选择,RemoteBuildPath 。RemoteLoadPath

                 

                2、AddressableAssetSettings设置

         3、构建

                

 三、导出信息分析:

        1、Assets同级目录下,ServerData内,包含所有所需文件。

        2、对应平台下。catalog.hash和catalog.json为版本检测和资源记录文件。其他为AB包。

        3、Assets/AddressableAssetsData/Android下为热更记录文件,打热更包所需。

四、打热更包:

        

        选择上述三、3的文件。更新后ServerData下catalog和修改的AB发生变化。

五、地址重定向:

Addressables.ResourceManager.InternalIdTransformFunc = LoadFunc;

public static bool CustomNet { get; private set; }public static string VersionURL;public static string AddressURL;private static string OldUrl = "http://localhost/";/// <summary>/// 设置热更地址/// </summary>/// <param name="_versionUrl">版本地址</param>/// <param name="_addressUrl">资源地址</param>public static void SetCustomAddress(string _versionUrl, string _addressUrl){CustomNet = true;VersionURL = _versionUrl;AddressURL = _addressUrl;
#if UNITY_EDITORUnityEngine.Debug.Log("设置版本地址:" + VersionURL);UnityEngine.Debug.Log("设置资源地址地址:" + AddressURL);
#endifAddressables.ResourceManager.InternalIdTransformFunc = LoadFunc;}private static string LoadFunc(IResourceLocation location){if (location.ResourceType == typeof(IAssetBundleResource) && location.InternalId.StartsWith("http")){string abAddress = location.InternalId.Replace(OldUrl, AddressURL);return abAddress;   }return location.InternalId;}

 六、热更,创建服务器,把ServerData/Android放上去。即可热更。

        1、热更下载的catalog文件在 Application.persistentDataPath

        2、下载的AB资源在 :C:\Users\Administrator\AppData\LocalLow\Unity

七、热更检测代码:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.ResourceManagement.AsyncOperations;
using UnityEngine.AddressableAssets.ResourceLocators;
using UnityEngine.Networking;public class Updater : MonoBehaviour
{public enum HotState{None,Version,Hash,Json,Download,StopDownload,}private HotState m_HotState = HotState.None;[SerializeField]public bool Hot = true;//多平台版本检测 -> 地址 [SerializeField]public string VersionURL = "CDN地址";[SerializeField]public string Catalog = "catalog";// 拉取CDN地址错误public System.Action<string> FirstAddressError;// 拉取hash版本地址错误public System.Action<string> VerionCheckError;// 拉取json版本地址错误public System.Action<string> VerionUpdateError;// 得到下载大小回调public System.Action<long> ResourceSize;// 下载进度回调public System.Action<float> DowonloadPercent;// 断网回调public System.Action DisconnectNet;// 重新联网回调public System.Action ReconnectNet;public static Updater Instance;private readonly List<object> _updateKeys = new List<object>();private IEnumerator IDownLoad;private NetworkReachability LastNet;private void Awake(){LastNet = Application.internetReachability;Instance = this;
#if UNITY_EDITORif (!Hot) // 动态设置分组模式{}
#endif}private void Start(){if (!Hot)EnterGame();elseStartCoroutine(SetAddress());}private IEnumerator SetAddress(){m_HotState = HotState.Version;if (Application.internetReachability == NetworkReachability.NotReachable){DisconnectNet?.Invoke();yield break;}UnityWebRequest request = UnityWebRequest.Post(VersionURL, "");yield return request.SendWebRequest();if (request.isHttpError || request.error != null){FirstAddressError?.Invoke(request.error);Debug.LogError("配置地址出错:" + request.error);yield break;}else{string datas = request.downloadHandler.text;CDNAddress CDN = JsonUtility.FromJson<CDNAddress>(datas);string url = CDN.GetGetAddressURL();Debug.Log("CDN :" + url);url = "http://192.168.11.51:8089/";AddressablesExt.SetCustomAddress(url + Catalog + ".hash", url);}StartCoroutine(DoUpdateAddressadble());}IEnumerator DoUpdateAddressadble(){m_HotState = HotState.Hash;if (Application.internetReachability == NetworkReachability.NotReachable){DisconnectNet?.Invoke();yield break;}AsyncOperationHandle<IResourceLocator> initHandle = Addressables.InitializeAsync();yield return initHandle;//检测更新AsyncOperationHandle<List<string>> checkHandle = Addressables.CheckForCatalogUpdates(false);yield return checkHandle;if (checkHandle.Status != AsyncOperationStatus.Succeeded){VerionCheckError?.Invoke(checkHandle.OperationException.ToString());Debug.LogError("版本检测失败:" + checkHandle.OperationException.ToString());yield break;}if (checkHandle.Result.Count > 0){m_HotState = HotState.Json;AsyncOperationHandle<List<IResourceLocator>> updateHandle = Addressables.UpdateCatalogs(checkHandle.Result, false);yield return updateHandle;if (updateHandle.Status != AsyncOperationStatus.Succeeded){Debug.LogError("版本更新失败:" + updateHandle.OperationException.ToString());VerionUpdateError?.Invoke(updateHandle.OperationException.ToString());yield break;}// 更新列表迭代器List<IResourceLocator> locators = updateHandle.Result;foreach (var locator in locators){_updateKeys.AddRange(locator.Keys);// key 里一堆乱七八糟的东西  }Addressables.Release(checkHandle);Addressables.Release(updateHandle);}else //版本已经更新过的,采用这种方式{IEnumerable<IResourceLocator> locators = Addressables.ResourceLocators;foreach (var locator in locators){_updateKeys.AddRange(locator.Keys);// key 里一堆乱七八糟的东西  }}AsyncOperationHandle<long> sizeHandle = Addressables.GetDownloadSizeAsync(_updateKeys as IEnumerable<object>);yield return sizeHandle;Debug.Log("热更资源总大小:" + NetFormat.GetDisplaySize(sizeHandle.Result));if (sizeHandle.Result > 0){ResourceSize?.Invoke(sizeHandle.Result);StartDownLoad();}else{Debug.Log("没有检测到更新 - 无需下载");EnterGame();}Addressables.Release(sizeHandle);}public void StartDownLoad(){IDownLoad = DownLoad();StartCoroutine(IDownLoad);}private void StopDownLoad(){m_HotState = HotState.StopDownload;StopCoroutine(IDownLoad);}private void Update(){if (Application.internetReachability != LastNet){switch (Application.internetReachability){case NetworkReachability.NotReachable:if (m_HotState == HotState.Download){StopDownLoad();}DisconnectNet?.Invoke();Debug.LogError("网络链接未打开");break;case NetworkReachability.ReachableViaCarrierDataNetwork:case NetworkReachability.ReachableViaLocalAreaNetwork:ReconnectNet?.Invoke();TryAgin();Debug.Log("流量 OR  WIFI");break;default:break;}LastNet = Application.internetReachability;}}public void TryAgin(){Debug.Log(m_HotState);switch (m_HotState){case HotState.None:break;case HotState.Version:StartCoroutine(SetAddress());break;case HotState.Hash:case HotState.Json:StartCoroutine(DoUpdateAddressadble());break;case HotState.Download:StartDownLoad();break;case HotState.StopDownload:StartDownLoad();break;default:break;}}public HotState GetHotState(){return m_HotState;}public void Quit(){Application.Quit();}
#if UNITY_EDITOR[UnityEditor.MenuItem("AATool/PrintState")]private static void PrnitState(){Debug.LogError(Instance.m_HotState);}
#endifprivate IEnumerator DownLoad(){m_HotState = HotState.Download;if (Application.internetReachability == NetworkReachability.NotReachable){DisconnectNet?.Invoke();yield break;}AsyncOperationHandle downHandle = Addressables.DownloadDependenciesAsync(_updateKeys as IEnumerable<object>, Addressables.MergeMode.Union, false);while (!downHandle.IsDone){float _bar = downHandle.GetDownloadStatus().Percent;DowonloadPercent?.Invoke(downHandle.GetDownloadStatus().Percent);UnityEngine.Debug.Log(_bar);yield return null;}yield return downHandle;if (downHandle.Status != AsyncOperationStatus.Succeeded){Debug.LogError("下载失败 - 重新尝试下载");StartDownLoad();Addressables.Release(downHandle);yield break;}else{Addressables.Release(downHandle);// 进入游戏EnterGame();}}// 进入游戏void EnterGame(){// TODODebug.Log("进入游戏");RootTools.MainScript.GetOrAddComponent<GameRoot>();Object.Destroy(gameObject);}private void OnApplicationQuit(){}private void OnApplicationFocus(bool focus){}
}


http://www.ppmy.cn/news/117673.html

相关文章

高性能计算:科学与工程问题的数值模拟与仿真应用都离不开它! ...

高性能计算作为一项强大的技术和工具&#xff0c;在科学和工程领域中的数值模拟和仿真应用方面发挥着至关重要的作用。本文将介绍高性能计算在解决科学和工程问题时的重要性&#xff0c;并探讨它在数值模拟和仿真方面的广泛应用。 科学探索与发现&#xff1a; 高性能计算为科学…

2023年上半年网络工程师上午真题及答案解析

1.固态硬盘的存储介质是( )。 A.光盘 B.闪存 C.软盘 D.磁盘 2.虚拟存储技术把( )有机地结合起来使用&#xff0c;从而得到一个更大容量的“内存”。 A.内存与外存 B.Cache与内存 C.寄存器与Cache D.Cache与外存 3.下列接口协议中&…

Dell戴尔灵越笔记本电脑Inspiron 15 7510原装出厂Windows10系统恢复原厂OEM系统

Dell戴尔灵越笔记本电脑Inspiron 15 7510原装出厂Windows10系统恢复原厂OEM系统 链接&#xff1a;https://pan.baidu.com/s/1Y5kNOQSy6rgXGCI_m7kndA?pwdn19t 提取码&#xff1a;n19t

记录 错误 C7510 “iterator”: 类型 从属名称的使用必须以“typename”为前缀 KMatrix_vector

1. 问题 “iterator”: 类型 从属名称的使用必须以“typename”为前缀 今天将我VS2017 的代码移植到VS2019上面时&#xff0c;产生了上面的错误&#xff0c;产生错误的代码片段如下 vector<vector<T>>::iterator it r.begin() row;r.erase(it);rowCount--;2. 解…

H3C 7510E配置syslog

1&#xff0c;登录到交换机。 2&#xff0c;配置正确的时间和时区&#xff0c;正确可忽略此步骤。时间不正确也能接收日志&#xff0c;会导致日志出现在错误的时间段。 display clock clock timezone beijing add 8 clock datetime 11:22:33 2020/01/013&#xff0c;配置日志内…

启动MARIADB常见问题

错误1&#xff1a;Cant connect to MySQL server on 127.0.0.1(10061) 错误2&#xff1a;Access denied for user ‘root’localhost (using password:YES) 接下来将介绍答主成功解决以上报错的方法&#xff1a; 错误1&#xff1a;Cant connect to MySQL server on 127.0.0.1(1…

ecshop助理上传报错 无法连接服务器:XML 文档只能有一个顶层元素。line2 b Deprecated/b:Assignig the Deprecated/b: 7510

无法连接服务器&#xff1a;XML 文档只能有一个顶层元素。line2 <b> Deprecated</b>:Assignig the return & 很多朋友的php程序当php的版本升级到5.3以后&#xff0c;会出现”Deprecated: Assigning the return value of new by reference is deprecat…

H3C S7500E V7 系列交换机产品及维护介绍--优化

H3C S7500E V7 系列交换机产品及维护介绍--优化 (单选题3道&#xff0c;多选题4道&#xff0c;判断题3道 满分100分) 一 . 单选题 (共3道题&#xff0c;共30分) 1.下面关于S7500E电源模块描述错误的是()&#xff08;10分&#xff09; A 支持两种电源输入&#xff0c;直流输…