Unity之Addressable使用注意事项

news2024/9/24 5:33:33

基本设置

Profile文件中配置资源构建路径和资源首次加载路径,资源如何设置了缓存,在首次加载之后会将再用缓存在缓存目录,后面将直接从缓存目录中读取,RemoteLoadPath一般要设置成可以动态修改类型的参数,方便项目发包时候进行使用
在这里插入图片描述

AddressableAssetSettings文件
DisableCatalogUpdateOnStartup 勾选改选项,禁止自动更新,项目资源下载一般需要提示玩家下载资源大小和下载进度,需要通过代码进行手动下载更新
BuildRemoteCatalog 创建远端资源的catalog,用于热更新资源
设置BuildPath和 LoadPath
根据自身网络状况设置资源最大的请求数和下载超时时间
在这里插入图片描述
Group文件注意设置BundleMode ,是否将group内的资源分散打包
在这里插入图片描述

Remote资源缓存

unity自身默认缓存路径是 C:\Users\admin\AppData\LocalLow\Unity
Addressable默认缓存路径 C:\Users\admin\AppData\LocalLow\Unity\项目名称_AdressableLoad
可以指定远端远端资源在本地缓存路径,需要注意的是,如果项目刚开始运行的时候没有手动设置缓存目录,在手动添加缓存目录之后默认缓存目录中已经存在的资源并不会被释放,每次加载读取的时候,先从手动设置的缓存目录中查找,在从默认缓存中查找,如果默认缓存中存在资源,则不会重新进行下载
创建CacheInitializationSettings文件,然后将改文件关联到AddressableAssetSettings的inititalizationObjects中,方法如下
在这里插入图片描述
在这里插入图片描述

手动设置缓存路径(如下图所示方式会缓存在工程根目录的AAAAAAA文件夹内,也可设置为 persistentDataPath 格式为{UnityEngine.Application.persistentDataPath})

在这里插入图片描述
在这里插入图片描述

每一个下载下来的bundle资源,会被缓存为_data 和_info两个文件,(猜测:_info是索引文件信息,_data是资源序列化内容)
在这里插入图片描述

代码部分

资源下载检测

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.ResourceManagement.AsyncOperations;

public class AddressableManager : MonoBehaviour
{
    public static AddressableManager instance;
    List<object> keys;//addressable ×ÊÔ´µÄlabel¼¯ºÏ£¬Ò»°ãͬһÀàÐ͵Ä×ÊÔ´ÓÃÒ»¸ölabel
    AsyncOperationStatus checkStatus;
    long totalDownloadSize = 0;
    public event Action<AsyncOperationStatus> onCheckFinish;

    // Start is called before the first frame update
    private void Awake()
    {
        instance = this;
        DontDestroyOnLoad(this.gameObject);
    }
    

    public IEnumerator CheckUpadate()
    {
        keys = new List<object>();
        totalDownloadSize = 0;
        yield return Addressables.InitializeAsync();
        Debug.Log("初始化检测更新");
        var checkHandle = Addressables.CheckForCatalogUpdates(false);//false是手动释放异步结果对象
        yield return checkHandle;
        Debug.Log("catalogs chek res:" + checkHandle.Status);
        if(checkHandle.Status == UnityEngine.ResourceManagement.AsyncOperations.AsyncOperationStatus.Succeeded)
        {
            List<string> catalogs = checkHandle.Result;
           
            if(catalogs != null && catalogs.Count > 0)
            {
                var updateHandle = Addressables.UpdateCatalogs(catalogs, false);
                yield return updateHandle;

                var catlogResult = updateHandle.Result;
                int idx = 0;
                foreach (var item in catlogResult)
                {
                    // var itemKeys = new List<object> { item.Keys };
                    // for (int i = 0; i < itemKeys.Count; i++)
                    // {
                    //     Debug.Log($"index:{idx},key:{itemKeys[i]}");
                    // }
                    foreach (var key in item.Keys)
                    {
                        if (key is string)
                        {
                            // if (!itemKeys.Any(x => x == key.ToString()))
                                keys.Add(key.ToString());
                        }
                    }
                    
                }
                // keys = new List<object> { catlogResult[0].Keys };
                Debug.Log("updatehandle res:" + updateHandle.Status);
                Debug.Log("updatehandle res:" + keys[0].ToString());
                if (updateHandle.Status == UnityEngine.ResourceManagement.AsyncOperations.AsyncOperationStatus.Succeeded)
                {
                    var sizeHandle = Addressables.GetDownloadSizeAsync(keys);
                    yield return sizeHandle;
                    if(sizeHandle.Status == UnityEngine.ResourceManagement.AsyncOperations.AsyncOperationStatus.Succeeded)
                    {
                        totalDownloadSize = sizeHandle.Result;
                        Debug.Log("下载资源大小" + (totalDownloadSize / 1024.0f / 1024.0f).ToString("0.00"));
                        checkStatus = AsyncOperationStatus.Succeeded;
                        CheckForUpdate(); 
                    }
                    else
                    {
                        checkStatus = AsyncOperationStatus.Failed;
                        CheckForUpdate();
                    }
                    Addressables.Release(sizeHandle);
                }
                else
                {
                    Debug.Log("¼ì²â¸üÐÂʧ°Ü£¬Çë¼ì²éÍøÂç×´¿ö");
                    checkStatus = AsyncOperationStatus.Failed;
                    CheckForUpdate();
                }
                Addressables.Release(updateHandle);

            }
            else
            {
                Debug.Log("不需要更新catlog");
                keys.Add("HD");
                keys.Add("Movie");
                var sizeHandel = Addressables.GetDownloadSizeAsync(keys);
                yield return sizeHandel;
                if(sizeHandel.Status == AsyncOperationStatus.Succeeded)
                {
                    totalDownloadSize = sizeHandel.Result;
                    Debug.Log("下载资源大小" + (totalDownloadSize / 1024.0f / 1024.0f).ToString("0.00"));
                    checkStatus = AsyncOperationStatus.Succeeded;
                    CheckForUpdate();
                }
                else
                {
                    Debug.Log("资源大小获取失败");
                    checkStatus = AsyncOperationStatus.Failed;
                    CheckForUpdate();
                }
                Addressables.Release(sizeHandel);
            }
        }

    }

     void CheckForUpdate()
    {
        if(checkStatus == AsyncOperationStatus.Succeeded && totalDownloadSize > 0)
        {
            StartCoroutine(ExcuteUpdate());
        }else onCheckFinish?.Invoke(checkStatus);
    }

    IEnumerator ExcuteUpdate()
    {
        var downloadDependenciesHandle = Addressables.DownloadDependenciesAsync(keys, Addressables.MergeMode.Union, false);//Addressables.DownloadDependenciesAsync(keys, false);
            while (downloadDependenciesHandle.Status == AsyncOperationStatus.None)
            {
                Debug.Log("当前下载进度:" + downloadDependenciesHandle.GetDownloadStatus().Percent);
                 yield return null;
            }
            if (downloadDependenciesHandle.Status == AsyncOperationStatus.Succeeded)
            {
                Debug.Log("download success");
            }
            else Debug.Log("download failed");
            Addressables.Release(downloadDependenciesHandle);    
            onCheckFinish?.Invoke(checkStatus);
    }

    /// <summary>
    /// »ñÈ¡µ¥¸ökey¶ÔÓ¦×ÊÔ´ÏÂÔØ´óС
    /// </summary>
    /// <param name="key"></param>
    /// <param name="onComplete"></param>
    /// <param name="onfailed"></param>
    public void GetDownloadSize(object key, Action<long> onComplete, Action onfailed = null)
    {
        var sizeHandle = Addressables.GetDownloadSizeAsync(key.ToString());
        sizeHandle.Completed += (result) => {
            if (result.Status == AsyncOperationStatus.Succeeded)
            {
                var downloadSize = result.Result;
                onComplete?.Invoke(downloadSize);
            }
            else onfailed?.Invoke();
            Addressables.Release(sizeHandle);
        };
    }
     public AsyncOperationHandle Download(object key, Action onComplete, Action onFailed   = null)
    {
        var downloadHandle = Addressables.DownloadDependenciesAsync(key.ToString(), true);
        downloadHandle.Completed += (result) => {
            if (result.Status == AsyncOperationStatus.Succeeded)
            { 
                onComplete?.Invoke();
            }
            else onFailed?.Invoke();
        };
        return downloadHandle;
    }
}

资源加载

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.ResourceManagement.AsyncOperations;

public class AssetManager : MonoBehaviour
{
    public AssetReference assetReference;
    [AssetReferenceUILabelRestriction("HD")]
    public AssetReference assetReferenceHD;
    public AssetReferenceGameObject assetReferenceGameObject;
    public AssetReferenceT<Texture> textureAsset;

    //private void Awake()
    //{
    //    Debug.Log("");
    //}

    void Start()
    {
        //AsyncOperationHandle<GameObject> res = assetReferenceGameObject.LoadAssetAsync();
        //res.Completed += Res_Completed;
        DontDestroyOnLoad(this.gameObject);
        // LoadByName("Prefab1");
        
        AddressableManager.instance.onCheckFinish += Instance_onCheckFinish;
        StartCoroutine(AddressableManager.instance.CheckUpadate());
    }

    private void Instance_onCheckFinish(AsyncOperationStatus status)
    {
        Debug.Log("finish status is " + status);
        Debug.Log("Path is " + Application.persistentDataPath);
        if (status == AsyncOperationStatus.Succeeded) 
        {
            LoadByName("Prefab3");
            LoadByName("SD");//prefab2
            InstantitateByName("Prefab4");
        }
    }

    private void Res_Completed(AsyncOperationHandle<GameObject> obj)
    {
        if (obj.Status == AsyncOperationStatus.Succeeded)
        {
            GameObject gob = Instantiate(obj.Result);
            Transform parent = GameObject.Find("Canvas").GetComponent<Transform>();
            gob.transform.SetParent(parent);
        }
    }

    private void LoadByName(string name)
    {
        Addressables.LoadAssetAsync<GameObject>(name).Completed += (handle) => {
            if (handle.Status == AsyncOperationStatus.Succeeded)
            {
                GameObject gob = Instantiate(handle.Result, GameObject.Find("Canvas").GetComponent<Transform>());
                Debug.Log($"加载资源完毕:{gob.name}");
            }else Debug.Log($"加载资源失败:{name}");

        };
    }

    private void InstantitateByName(string name)
    {
        Addressables.InstantiateAsync(name).Completed += (handle) => {
            if (handle.Status == AsyncOperationStatus.Succeeded)
            {
                GameObject gob = handle.Result;
                gob.transform.SetParent(GameObject.Find("Canvas").GetComponent<Transform>());
                gob.GetComponent<RectTransform>().anchoredPosition = Vector2.zero;
                Debug.Log("实例化对象创建完毕" + gob.name);
            }else Debug.Log($"加载资源失败:{name}");
        };
    }


}

配置文件

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ConfigManager 
{
    public static string CdnUrl = "http://192.168.133.144/Files/dev";
    //public static string RemoteCachePath { get { return Application.persistentDataPath + "/android"; } }
    public static string RemoteCachePath { get {
#if UNITY_EDITOR
            return "AddresableAsset/android";
#else
            return Application.persistentDataPath+"/AddresableAsset"; 
#endif

        }
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/400408.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

[oeasy]python0104_指示灯_显示_LED_辉光管_霓虹灯

编码进化 回忆上次内容 x86、arm、riscv等基础架构 都是二进制的包括各种数据、指令 但是我们接触到的东西 都是屏幕显示出来的字符 计算机 显示出来的 一个个具体的字型 计算机中用来展示的字型 究竟是 如何进化的 呢&#xff1f;&#x1f914;&#x1f914; 模拟电路时…

在线客服机器人是什么?有什么用处?

在线客服机器人是客服自动智能问答 真人模拟应答以及意向分类 高效低成本可以同时进行一对多服务&#xff0c;而在一些情况下&#xff0c;在线客服机器人还可以进行客户接待&#xff0c;完全代替人工客服&#xff0c;提高整个客服中心的接待量。在这里我们拿ttkefu在线机器人为…

Spring学习——Maven进阶

分模块开发与设计 创建模块 书写模块代码 通过maven指令安装模块到本地仓库(install指令) 在pom.xml中导入坐标执行maven的install命令将模块安装到本地maven仓库 团队内部开发可以发布模块功能到团队内部可共享的仓库中&#xff08;私服) 依赖管理 依赖指当前项目运行所需…

JAVA SE:多线程

一、线程简介多任务&#xff0c;看似同时在做&#xff0c;实际上同一时间只做一件事多线程&#xff0c;相当于路上多加一条车道普通方法vs多线程&#xff1a; 程序、进程、线程&#xff1a;程序&#xff1a;静态的概念&#xff0c;程序和数据的有序集合进程&#xff1a;操作系统…

CleanMyMac X4.20最新Mac系统垃圾清理工具

CleanMyMac X是一款Mac系统垃圾清理工具,可以清除Mac系统多余的语言包、系统缓存、应用程序、PowerPc软件运行库等,是硬盘瘦身的好工具。在面对一款多功能型的软件时&#xff0c;复杂的操作面板是最容易让人头疼的&#xff0c;好在 CleanMyMac 一直以来都原生支持简体中文语言&…

python第五天作业~基础练习

目录 求十进制数字9的二进制编码&#xff1a; 求十进制数字9的二进制编码中的1的数量&#xff1a; 作业15&#xff1a;求1~100之间不能被3整除的数之和 作业16&#xff1a;给定一个正整数N,找出1到N&#xff08;含&#xff09;之间所有质数的总和 作业19&#xff1a;计算PI&…

为什么那么多人转行编程都首选Java

计算机专业通常从C语言开始学&#xff0c;非计算机专业想要转行编程首选Java的主要原因&#xff1a;市场需求量大。Java可以用于开发各种应用程序&#xff0c;包括企业级Web应用程序、移动应用程序、桌面应用程序、游戏、嵌入式系统、云基础设施等等。在游戏领域也有两大经典游…

Meta带头甩卖 VR头显打起价格战

新春三月&#xff0c;准备入手VR头显的“等等党”终于迎来降价利好。以Meta为首的一众VR厂商们纷纷打折&#xff0c;无论是为了清理库存、回收成本还是让步硬件新品&#xff0c;普通消费者都喜闻乐见。 上周五&#xff0c;Meta 率先官宣Meta Quest Pro与Meta Quest 2 的256GB版…

效率工具-快速创建虚拟机,Vagrant真香!

工欲善其事&#xff0c;必先利其器&#xff0c;开发环境和开发工具就是我们开发人员的剑&#xff0c;所以我们需要一个快并且好用的剑。本文是向大家介绍虚拟机创建vagrant&#xff0c;它能够实现开发人员本机快速创建虚拟机&#xff0c;能够带来高效学习各种技术价值。1 Vagra…

我的投稿之旅

一、铁道科学与工程学报选择这个期刊的原因是&#xff1a;感觉影响因子较低&#xff0c;而且实验室有师兄师姐中过这个期刊&#xff0c;所以抱着试一试的心态投了。投稿之前需要去官网注册账号由于方向不一致&#xff0c;被退稿了“您的稿件内容不属于本刊刊载范畴&#xff0c;…

Content-Type (MIME) el-upload文件、图片上传 | 文件改名 | 大文件 | 文件下载

MIME 为数据格式标签&#xff1b;最初 MIME 是用于电子邮件系统的&#xff0c;后来 HTTP 也采用了这一方案。 在HTTP协议消息头中&#xff0c;使用Content-Type来表示请求和响应中的媒体类型信息。 Content-Type&#xff1a;type/subtype ;parametertype 主类型&#xff0c;任…

【LeetCode每日一题】——135.分发糖果

文章目录一【题目类别】二【题目难度】三【题目编号】四【题目描述】五【题目示例】六【解题思路】七【题目提示】八【时间频度】九【代码实现】十【提交结果】一【题目类别】 贪心算法 二【题目难度】 困难 三【题目编号】 135.分发糖果 四【题目描述】 n 个孩子站成一…

【论文研读】无人机飞行模拟仿真平台设计

无人机飞行模拟仿真平台设计 摘要&#xff1a; 为提高飞行控制算法的研发效率,降低研发成本,基于数字孪生技术设计一个无人机硬件在环飞行模拟仿真平台。从几何、物理和行为3个方面研究无人机数字模型构建方法,将物理实体以数字化方式呈现。设计一种多元融合场景建模法,依据属…

Java--JMH--性能测试--测试软件运行效率/时间--StopWatch

写在前面: 很多时候想要测试代码运行时间&#xff0c;或者比较2个运行的效率。 最简单的方法就是Sytem.currentTimeMillis记录2开始和结束时间来算 但是Java 代码越执行越快&#xff0c;放在后面的方法会有优势&#xff0c;这个原因受留个眼&#xff0c;以后研究。大概有受类加…

RedisCluster集群模式下master宕机主从切换期间Lettuce连接Redis无法使用报错Redis command timed out的问题

背景springboot使用redisTemplate访问redis cluster&#xff08;三主三从&#xff09;&#xff0c;底层是Lettuce&#xff0c;当其中一个master挂掉后&#xff0c;slave正常升为master&#xff0c;程序报错 Redis commond timed out after 6 seconds。解决手动连接集群&#xf…

【三维几何学习】网格上低分辨率的分割结果到高分辨率的投影与可视化

网格上低分辨率的分割结果到高分辨率的投影与可视化引言一、到高分辨率的投影1.1 准确率1.2 主要代码1.3 投影核心代码二、可视化代码引言 三角网格的结构特性决定了其仅用少量三角形即可表示一个完整的3D模型。增加其分辨率可以展示更多模型的形状细节。对于网格分割来说&…

可复用测试用例描述要素

测试用例的输入、操作、预期结果和评估标准、前提条件是测试用例不可少的要素&#xff0c;但对于可复用测试用例而言&#xff0c;这是不够的。本文在文献规定的测试用例要素基础上&#xff0c;增加了新的内容。从而从多个角度完整地对可复用测试用例进行了描述&#xff0c;为可…

从0开始学IntelliJ Plugin开发:一、配置环境

前言 作为一个javaer&#xff0c;相信大家平时开发都多多少少使用了一些idea的插件&#xff0c;那么在享受插件便利的同时&#xff0c;有没有好奇插件是如何开发的 笔者怀着这份好奇开始了idea插件开发学习之路&#xff0c;同时把学习的心得体会整理成系列文章作为学习笔记供…

探访人工智能领跑者:纷享销客携手30+TOP高科技企业走进旷视科技

拥有全球规模领先的计算机视觉研究院&#xff1b; 揽获28项世界顶级AI竞赛冠军&#xff1b; 世界级人工智能公司&#xff1b; 没错&#xff0c;它就是人工智能行业的务实者和领跑者&#xff0c;旷视科技。 3月3日&#xff0c;北京软件和信息服务业协会联合纷享销客&#xff0c;…

macOS 13.3 Beta 3 (22E5236f)With OpenCore 0.9.1开发版 and winPE双引导分区原版镜像

原文地址&#xff1a;http://www.imacosx.cn/112494.html&#xff08;转载请注明出处&#xff09;镜像特点完全由黑果魏叔官方制作&#xff0c;针对各种机型进行默认配置&#xff0c;让黑苹果安装不再困难。系统镜像设置为双引导分区&#xff0c;全面去除clover引导分区&#x…