Unity Addressables热更流程

这篇具有很好参考价值的文章主要介绍了Unity Addressables热更流程。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

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

二、构建

        构建前设置:

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

                Unity Addressables热更流程 

                2、AddressableAssetSettings设置

Unity Addressables热更流程

         3、构建

                Unity Addressables热更流程

 三、导出信息分析:

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

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

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

四、打热更包:

        Unity Addressables热更流程

        选择上述三、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_EDITOR
        UnityEngine.Debug.Log("设置版本地址:" + VersionURL);
        UnityEngine.Debug.Log("设置资源地址地址:" + AddressURL);
#endif
        Addressables.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

七、热更检测代码:文章来源地址https://www.toymoban.com/news/detail-497901.html

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_EDITOR
        if (!Hot) // 动态设置分组模式
        {
        }
#endif
    }
    private void Start()
    {
        if (!Hot)
            EnterGame();
        else
            StartCoroutine(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);
    }
#endif
    private 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()
    {
        // TODO
        Debug.Log("进入游戏");
        RootTools.MainScript.GetOrAddComponent<GameRoot>();
        Object.Destroy(gameObject);
    }
    private void OnApplicationQuit()
    {

    }
    private void OnApplicationFocus(bool focus)
    {

    }
}

到了这里,关于Unity Addressables热更流程的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Unity Addressables资源管理 主设置面板

    Addressables资源管理总目录 位置1 位置2     这个是全局路径配置的选择 可以点击 Manager Profiles 打开路径配置面板 打包路径设置   Send Profiler Events  打开这个选项,才能在Event Viewer窗口看到资源的事件 Log Runtime Exceptions  记录运行时的异常日志   默认情况下Addressables只记录警告

    2024年02月13日
    浏览(49)
  • Unity Addressables资源管理 安装和使用本地加载

    Addressables资源管理总目录 1.安装 打开Unity内置的 PackagerManager窗口 搜索Add即可找到 安装版本为1.19.19 2.添加Group 点击 Group 菜单 打开窗口 点击 Create Addressables Settings 创建可寻址设置 Assets下会生成一个  AddressableAssetsData 文件夹 其中可以看见面板中的  Default Local Group  默认组 资

    2023年04月13日
    浏览(35)
  • Unity Addressables学习笔记(3)---加载远程场景Scenes

    我是创建在Resources/Scenes目录下,如图: Game1Group就是我新创建的一个Group用来存放场景1的所有资源,分组的配置跟Remote一样,都是远程的,加载地址是我本地启动的web服务器地址,URL里WebGL那个目录也不是必须的,根据自己实际的来。 上边的图就是拖完的状态。 我是在最开始

    2024年01月25日
    浏览(74)
  • Unity_热更方案

    热更是指在游戏已经发布和运行后,仍然能够更新游戏内容、修复错误或添加新功能 具体的来说有几种方法可以实现: 这种方法比较基础,但对于一些小型项目或原型来说,是一种有效的热更方式 这是之前比较通用的一种方法 Lua热更是针对脚本的更新,需要有一个稳定的热

    2024年02月07日
    浏览(60)
  • Unity Addressables学习笔记(1)---创建远程服务器加载资源

    Unity Addressables学习笔记—汇总 Bulid Path选择RemoteBuildPath Load Path我选择了custom,地址是http://localhost:8080/WebGL/ 遇坑1 :最开始我选择的Build Path 是 LocalBuildPath,Load Path是custom的时候报错如下: 解决办法:把Build Path 改为RemoteBuildPath后才好,我也不知道为什么不能把本地的资源放到远程

    2024年02月14日
    浏览(41)
  • Unity AssetBundle资源热更插件

    取消 IsEditorMode 勾选: 采用AssetBundle的方式加载游戏内的资源 激活 IsEditorMode 勾选: 使用AssetDatabase.LoadAssetAtPath的方式加载 仅Editor 温馨提示: IsEditorMode 受到宏限制 如果你非 UNITY_EDITOR模式下 ( 当年在真机的时候 ) IsEditorMode强制为False 避免用户打包后忘记关了 新建一个AssetBundl

    2024年02月11日
    浏览(46)
  • 【Unity实战】HybridCLR热更快速集成

    本文假设你已经通过UPM导入了HybridCLR、Addressables、il2cpp支持并具有一定的C#基础和Unity编辑器操作能力。 由于本文主打快速集成,故将Assembly-CSharp划入到热更新DLL。 理论上成熟的项目应该用Assembly Definition进行精细划分以便于管理和缩短编译时间。但是若掌握不好,划分不明白

    2024年02月03日
    浏览(49)
  • Unity热更模块基于 HybridCLR + Addressable

    代码地址: GitHub - ManoKing/FFramework: 基于HybridCLR + Addressable的热更新框架,提供例子基于QFramework+URP开发 基于HybridCLR + Addressable的热更新框架,提供例子基于QFramework+URP开发 - GitHub - ManoKing/FFramework: 基于HybridCLR + Addressable的热更新框架,提供例子基于QFramework+URP开发 https://github.

    2023年04月14日
    浏览(47)
  • Unity使用 Addressables 预加载所有资源,提现加载资源,发布webgl加载缓慢问题

    Addressables 我也是刚接触,知道的不是很多,基本的用法还是知道一些的 1 .在Window–Package Manager里找到Addressables进行安装   2.选择资源,点击Assets中的一个资源,在Inspector面板上就会出现一个勾选Assressable,也就是是否加入资源打包的分组,和AssetBundle分组是一个性质。选上以

    2023年04月08日
    浏览(46)
  • Unity使用TextMeshPro多字体和材质热更

    最近Unity项目中使用到TextMeshPro做聊天,需要支持部分字体带描边,部分字体不带描边。想到的决解方案是:TextMeshPro支持多字体展示(具体可以查看组件的官方案例Link Example),就做了两个字体一个是带描边的一个是不带描边的。 但是有个问题是多出来的一个字体需要放在

    2024年02月16日
    浏览(60)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包