【Unity知识点详解】Addressables的资源加载

        今天来简单介绍一下Addressables,并介绍一下如何通过AssetName加载单个资源、如何通过Label加载多个资源、以及如何通过List<string>加载多个资源。由于Addressables的资源加载均为异步加载,所以今天给大家介绍如何使用StartCoroutine、如何使用Async/Await、如何使用Completed回调的三种方式加载。

        

准备工作

        首先我们需要在Unity菜单栏Window中找到Package Manager,在Package Manager中下载并安装Addressables组件。

        我们在项目中准备了一些游戏资源,并且可以在Inspector窗口下将资源选择为加载资源,对于目录而言也可以整体选择为加载资源。

        选择完加载资源之后,我们通过Window->Asset Management->Addressables->Groups路径页签打开Addressables Groups窗口,Addressables Groups中列举的则是所有选中的加载资源。

        我们可以对每个资源进行Label分类,当然不分类默认default也没关系。点击Manage Labels可以打开Labels窗口自定义自己所需要的标签。关于Label有什么用往后看。

使用StartCoroutine加载资源

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

public class LoadCoroutine : MonoBehaviour
{
    public void Awake()
    {
        StartCoroutine(LoadAssetAsync("LanguageConfig"));
        StartCoroutine(LoadMultipleAssetAsync("Config"));
        StartCoroutine(LoadMultipleAssetAsync(new List<string>() { "LanguageConfig", "RoleConfig", "Prefab" }));
    }

    /// <summary>单资源加载</summary>
    /// <param name="pAssetName"></param>
    public IEnumerator LoadAssetAsync(string pAssetName)
    {
        AsyncOperationHandle asyncOperationHandle = Addressables.LoadAssetAsync<UnityEngine.Object>(pAssetName);
        yield return asyncOperationHandle;
        LoadAssetAsyncCompleted(asyncOperationHandle);
    }

    /// <summary>多资源加载(通过Label)</summary>
    /// <param name="pLabelsName"></param>
    public IEnumerator LoadMultipleAssetAsync(string pLabelsName)
    {
        AsyncOperationHandle<IList<UnityEngine.Object>> asyncOperationHandle = Addressables.LoadAssetsAsync<UnityEngine.Object>(pLabelsName, null);
        yield return asyncOperationHandle;
        LoadAssetAsyncCompleted(asyncOperationHandle);
    }

    /// <summary>多资源加载(通过List)</summary>
    /// <param name="pNameList"></param>
    public IEnumerator LoadMultipleAssetAsync(List<string> pNameList)
    {
        AsyncOperationHandle<IList<UnityEngine.Object>> asyncOperationHandle = Addressables.LoadAssetsAsync<UnityEngine.Object>(pNameList, null, Addressables.MergeMode.Union, false);
        yield return asyncOperationHandle;
        LoadMultipleAssetAsyncCompleted(asyncOperationHandle);
    }


    /// <summary>加载完成回调</summary>
    public void LoadAssetAsyncCompleted(AsyncOperationHandle pHandle)
    {
        if (pHandle.Status == AsyncOperationStatus.Succeeded)
        {
            if (pHandle.Result is List<UnityEngine.Object>)
            {
                List<UnityEngine.Object> assetList = pHandle.Result as List<UnityEngine.Object>;
                for (int index = 0; index < assetList.Count; index++)
                {
                    Debug.LogError(assetList[index]);
                }
            }
            else
            {
                Debug.LogError(pHandle.Result);
            }
        }
    }

    /// <summary>加载完成回调</summary>
    public void LoadMultipleAssetAsyncCompleted(AsyncOperationHandle<IList<UnityEngine.Object>> pHandle)
    {
        if (pHandle.Status == AsyncOperationStatus.Succeeded)
        {
            if (pHandle.Result is List<UnityEngine.Object>)
            {
                List<UnityEngine.Object> assetList = pHandle.Result as List<UnityEngine.Object>;
                for (int index = 0; index < assetList.Count; index++)
                {
                    Debug.LogError(assetList[index]);
                }
            }
            else
            {
                Debug.LogError(pHandle.Result);
            }
        }
    }
}

        我们这里先来介绍使用StartCoroutine加载资源,这里我提供了三种加载资源的方法。

public IEnumerator LoadAssetAsync(string pAssetName) 是通过资源名称加载资源,这个方法只能加载单个资源,这里的参数pAssetName指代的则是Addressables Groups窗口中的Addressable Name。这里的Addressable Name是可以自行修改的,资源选取的时候默认是全路径名称,就像上面截图中MainPanel一样显示的是全路径。我们在开发中可以根据自己的需求进行修改。

public IEnumerator LoadMultipleAssetAsync(string pLabelsName)是通过Label名称加载资源的,一次可以加载一个或多个资源。这个方法会将所有标记为pLabelsName的资源加载进来,并且返回一个IList<TObject>类型的结果。

public IEnumerator LoadMultipleAssetAsync(List<string> pNameList)是通过一个名称列表加载资源的,一次可以加载一个或多个资源。这里的pNameList参数既可以包含单个pAssetName,也可以包含pLabelsName,或者同时包含pAssetName和pLabelsName。加载完成后同样会返回一个IList<TObject>类型的结果,这里需要说明的是一个资源只会被加载一次,例如pNameList中包含了资源名MainPanel,又包含了Label名Prefab,同时MainPanel又被标记为了Prefab,此时加载返回的资源结果中只会有一个MainPanel。

        以上三种方法均是调用了Addressables类中提供的资源加载接口,Addressables中则是包含了所有的资源加载接口,感兴趣的小伙伴可以自己研究。

        Addressables的加载接口返回的均为一个AsyncOperationHandle对象,由于AsyncOperationHandle对象继承自IEnumerator,所以我们可以将加载方法写成一个协程函数通过StartCoroutine来进行调用。加载完成后我们可以通过AsyncOperationHandle.Result获取加载的资源,Result为object类型在实际使用时需要根据实际类型进行转换后使用。

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

public class LoadAsyncAwait : MonoBehaviour
{
    public void Awake()
    {
        LoadAssetAsync("LanguageConfig");
        LoadMultipleAssetAsync("Config");
        LoadMultipleAssetAsync(new List<string>() { "LanguageConfig", "MainPanel", "SettingPanel" });
    }

    /// <summary>单资源加载</summary>
    /// <param name="pAssetName"></param>
    public async void LoadAssetAsync(string pAssetName)
    {
        AsyncOperationHandle asyncOperationHandle = Addressables.LoadAssetAsync<UnityEngine.Object>(pAssetName);
        await asyncOperationHandle.Task;
        LoadAssetAsyncCompleted(asyncOperationHandle);
    }

    /// <summary>多资源加载(通过Label)</summary>
    /// <param name="pLabelsName"></param>
    public async void LoadMultipleAssetAsync(string pLabelsName)
    {
        AsyncOperationHandle asyncOperationHandle = Addressables.LoadAssetsAsync<UnityEngine.Object>(pLabelsName, null);
        await asyncOperationHandle.Task;
        LoadAssetAsyncCompleted(asyncOperationHandle);
    }

    /// <summary>多资源加载(通过List)</summary>
    /// <param name="pNameList"></param>
    public async void LoadMultipleAssetAsync(List<string> pNameList)
    {
        AsyncOperationHandle<IList<UnityEngine.Object>> asyncOperationHandle = Addressables.LoadAssetsAsync<UnityEngine.Object>(pNameList, null, Addressables.MergeMode.Union, false);
        await asyncOperationHandle.Task;
        LoadMultipleAssetAsyncCompleted(asyncOperationHandle);
    }


    /// <summary>加载完成回调</summary>
    public void LoadAssetAsyncCompleted(AsyncOperationHandle pHandle)
    {
        if (pHandle.Status == AsyncOperationStatus.Succeeded)
        {
            if (pHandle.Result is List<UnityEngine.Object>)
            {
                List<UnityEngine.Object> assetList = pHandle.Result as List<UnityEngine.Object>;
                for (int index = 0; index < assetList.Count; index++)
                {
                    Debug.LogError(assetList[index]);
                }
            }
            else
            {
                Debug.LogError(pHandle.Result);
            }
        }
    }

    /// <summary>加载完成回调</summary>
    public void LoadMultipleAssetAsyncCompleted(AsyncOperationHandle<IList<UnityEngine.Object>> pHandle)
    {
        if (pHandle.Status == AsyncOperationStatus.Succeeded)
        {
            if (pHandle.Result is List<UnityEngine.Object>)
            {
                List<UnityEngine.Object> assetList = pHandle.Result as List<UnityEngine.Object>;
                for (int index = 0; index < assetList.Count; index++)
                {
                    Debug.LogError(assetList[index]);
                }
            }
            else
            {
                Debug.LogError(pHandle.Result);
            }
        }
    }
}

使用Async/Await加载资源

        接下来介绍的是使用Async/Await方式加载资源,同样示例中展示了通过AssetName加载资源、通过Label加载资源、以及通过List<string>加载资源,同样是调用Addressables类的加载接口加载资源。不同的是Async/Await方式使用的是AsyncOperationHandle中提供的Task异步类,在函数写法上略有不同。相比StartCoroutine而言Async/Await的调用方式与普通函数无异。在加载完成之后,同样从AsyncOperationHandle.Result获取加载的资源资源对象。   

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

public class LoadCompleted : MonoBehaviour
{
    public void Awake()
    {
        LoadAssetAsync("LanguageConfig", LoadAssetAsyncCompleted);
        LoadMultipleAssetAsync("Config", LoadMultipleAssetAsyncCompleted);
        LoadMultipleAssetAsync(new List<string>() { "LanguageConfig", "MainPanel", "SettingPanel" }, LoadMultipleAssetAsyncCompleted);
    }

    /// <summary>单资源加载</summary>
    /// <param name="pAssetName"></param>
    /// <param name="LoadComplete"></param>
    public void LoadAssetAsync(string pAssetName, Action<AsyncOperationHandle> LoadComplete)
    {
        AsyncOperationHandle asyncOperationHandle = Addressables.LoadAssetAsync<UnityEngine.Object>(pAssetName);
        asyncOperationHandle.Completed += LoadComplete;
    }

    /// <summary>多资源加载(通过Label)</summary>
    /// <param name="pLabelsName"></param>
    /// <param name="LoadComplete"></param>
    public void LoadMultipleAssetAsync(string pLabelsName, Action<AsyncOperationHandle<IList<UnityEngine.Object>>> LoadComplete)
    {
        AsyncOperationHandle<IList<UnityEngine.Object>> asyncOperationHandle = Addressables.LoadAssetsAsync<UnityEngine.Object>(pLabelsName, null);
        asyncOperationHandle.Completed += LoadComplete;
    }

    /// <summary>多资源加载(通过List)</summary>
    /// <param name="pNameList"></param>
    /// <param name="LoadComplete"></param>
    public void LoadMultipleAssetAsync(List<string> pNameList, Action<AsyncOperationHandle<IList<UnityEngine.Object>>> LoadComplete)
    {
        AsyncOperationHandle<IList<UnityEngine.Object>> asyncOperationHandle = Addressables.LoadAssetsAsync<UnityEngine.Object>(pNameList, null, Addressables.MergeMode.Union, false);
        asyncOperationHandle.Completed += LoadComplete;
    }

    /// <summary>加载完成回调</summary>
    public void LoadAssetAsyncCompleted(AsyncOperationHandle pHandle)
    {
        if (pHandle.Status == AsyncOperationStatus.Succeeded)
        {
            if (pHandle.Result is List<UnityEngine.Object>)
            {
                List<UnityEngine.Object> assetList = pHandle.Result as List<UnityEngine.Object>;
                for (int index = 0; index < assetList.Count; index++)
                {
                    Debug.LogError(assetList[index]);
                }
            }
            else
            {
                Debug.LogError(pHandle.Result);
            }
        }
    }

    /// <summary>加载完成回调</summary>
    public void LoadMultipleAssetAsyncCompleted(AsyncOperationHandle<IList<UnityEngine.Object>> pHandle)
    {
        if (pHandle.Status == AsyncOperationStatus.Succeeded)
        {
            if (pHandle.Result is List<UnityEngine.Object>)
            {
                List<UnityEngine.Object> assetList = pHandle.Result as List<UnityEngine.Object>;
                for (int index = 0; index < assetList.Count; index++)
                {
                    Debug.LogError(assetList[index]);
                }
            }
            else
            {
                Debug.LogError(pHandle.Result);
            }
        }
    }
}

使用Completed回调加载资源

        最后一种方式是使用Completed回调来加载资源。与前两种方式最大的不同就是在调用方法时需要传入回调函数,当资源加载完成时则会调用回调函数。回调函数则会返回一个AsyncOperationHandle类型的参数,使用方法与前两种方式相同。

官方文档链接

Loading Addressable assets:https://docs.unity3d.com/Packages/com.unity.addressables@1.18/manual/LoadingAddressableAssets.html

Addressables类:https://docs.unity3d.com/Packages/com.unity.addressables@1.18/api/UnityEngine.AddressableAssets.Addressables.html

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

WHAT - 用户登录系列(二)- 单点登录 SSO

目录 一、认证机制1.1 基于会话的认证&#xff08;Session-based Authentication&#xff09;1. 介绍2. 基本流程 1.2 JSON Web Tokens (JWT)1. 介绍2. jwt 组成3. 基本流程4. 阻止列表5. 刷新令牌 二、单点登录&#xff1a;SSO2.1 单系统登录2.2 SSO 介绍2.3 SSO 登录2.4 SSO …

arcgis api for javascript点击获取要素错乱的问题

今天帮同事看了一个前端地图点击的问题&#xff1a;点击时总会获取到周边的图元&#xff0c;即使我点击线的周围&#xff0c;也是能获取到的&#xff0c;除非离得特别远。 地图组件用的是arcgis api, 图层类是grahicslayer,要素类型是线。这是添加图元的代码&#xff1a; grap…

STM32高级控制定时器之输入捕获模式

目录 概述 1 输入捕获模式 1.1 原理介绍 1.2 实现步骤 1.3 发生输入捕获流程 2 使用STM32Cube配置工程 2.1 软件环境 2.2 配置参数 2.3 生成项目文件 3 功能实现 3.1 PWM调制占空比函数 3.2 应用函数库 4 测试 4.1 功能框图 4.2 运行结果 源代码下载地址&#xf…

基于ELK的日志管理【开发实践】

文章目录 一、ELK简介1.1 ELK的作用与应用1.2 ELK的组成1.3 Elasticsearch1.4 Logstash1.5 Kibana1.6 ELK架构简述1.7 基础知识1.7.1 数据格式1.7.2 正排索引和倒排索引1.7.3 全文搜索 二、ES入门---基于HTTP的使用方式&#xff08;了解&#xff09;2.1 索引操作2.1.1 创建索引…

探索无限可能:API平台引领数据驱动的新时代

在数字化浪潮的推动下&#xff0c;数据已成为推动商业创新和增长的核心动力。然而&#xff0c;数据的获取、整合和应用并非易事&#xff0c;需要跨越技术、安全和效率等多重挑战。幸运的是&#xff0c;API&#xff08;应用程序接口&#xff09;平台的出现&#xff0c;为我们打开…

docker 安装mysql,redis,rabbitmq

文章目录 docker 安装ngnix&#xff0c;mysql,redis,rabbitmq安装docker1.安装下载docker-ce源命令2.安装docker3.查看版本4.查看docker状态5.启动docker6.测试安装ngnix 安装mysql8.0.361.拉取mysql镜像2.安装mysql8 安装redis1.拉取redis7.0.11镜像2.安装redis3.进入容器内部…

159.二叉树:二叉树的层平均值(力扣)

代码解决 /*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* TreeNode *right;* TreeNode() : val(0), left(nullptr), right(nullptr) {}* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}* Tre…

mybatisPlus3.5.1有个奇葩bug的解决方法

mybatisPlus3.5.1有个奇葩bug的解决方法 文章目录 1.啥bug&#xff1f;1.1mybatisPlus官网及GitHub项目地址1.2 bug问题 2.解决方法2.1根据报错修改表中字段2.2 升级JSqlParser依赖的版本2.3升级mybatisPlus的版本 3.mysql关键字大全4.总结 1.啥bug&#xff1f; 1.1mybatisPlu…

上传RKP 证书签名请求息上传到 Google 的后端服务器

上传证书签名请求 1.准备环境&#xff1a;OK pip3 install google-auth2.13.0 requests2.28下载 device_info_uploader.py 。 没找到先跳过 选项 1&#xff1a;通过 GCP 帐户使用 device_info_uploader.py 运行脚本。 ./device_info_uploader.py --credentials /secure/s…

软件测试可发现所有bug吗?有什么样的原则和目的?

在今天的高度数字化时代&#xff0c;软件测试的重要性不可忽视。这是一种系统性的过程&#xff0c;通过对软件系统进行评估和验证&#xff0c;以确定其是否满足预期要求。在软件开发的各个阶段&#xff0c;软件测试都扮演着至关重要的角色。它涉及到软件功能、性能、安全性等多…

基于Spring Boot框架的分页查询和文件上传

分页查询 分析 要想从数据库中进行分页查询&#xff0c;我们要使用LIMIT关键字&#xff0c;格式为&#xff1a;limit 开始索引 每页显示的条数 假设一页想展示10条数据 查询第1页数据的SQL语句是&#xff1a; select * from emp limit 0,10; 查询第2页数据的SQL语句是&…

【推荐】用scss循环zoom缩放比例,解决可视化大屏在不同分辨率屏幕下的适配问题

方法1&#xff1a; 指定几种常规屏幕宽度&#xff08;用这种方式就必须要强制用户全屏查看页面&#xff0c;在固定的宽度下才能达到比较不错的显示效果&#xff09; // 适配不同分辨率的页面---------------------------------------- html {overflow: hidden;width: 1920px;…

光电耦合器:航天航空领域的先进连接技术

光电耦合器作为一种关键的电子连接器&#xff0c;在航天航空领域扮演着重要角色。本文将深入探讨光电耦合器在航天航空领域的应用及其技术特点。 光电耦合器在航天航空领域的应用 光电耦合器作为一种高可靠性、高速传输、抗干扰能力强的连接器&#xff0c;在航天航空领域有着广…

Mybatis 查询TypeHandler使用,转译查询数据(逗号分隔转List)

创建自定义的Hanndler /*** Package: com.datalyg.common.core.handler* ClassName: CommaSeparatedStringTypeHandler* Author: dujiayu* Description: 用于mybatis 解析逗号拼接字符串* Date: 2024/5/29 10:03* Version: 1.0*/ public class CommaSeparatedStringTypeHandle…

U盘格式化怎么操作?快来学这4种法

U盘格式化怎么操作&#xff1f;在计算机领域中&#xff0c;格式化通常指对存储设备&#xff08;如硬盘、U盘&#xff09;进行格式化操作&#xff0c;清空其中的数据并重新建立文件系统&#xff0c;以便进行数据存储和管理。 U盘格式化一共有哪些方法&#xff1f;在格式化U盘之…

暑期来临,AI智能视频分析方案筑牢防溺水安全屏障

随着夏季暑期的来临&#xff0c;未成年人溺水事故频发。传统的防溺水方式往往依赖于人工巡逻和警示标识的设置&#xff0c;但这种方式存在人力不足、反应速度慢等局限性。近年来&#xff0c;随着视频监控智能分析技术的不断发展&#xff0c;其在夏季防溺水中的应用也日益凸显出…

Kubernetes 系统监控Metrics Server、HorizontalPodAutoscaler、Prometheus

Metrics Server Linux 系统命令 top 能够实时显示当前系统的 CPU 和内存利用率&#xff0c;它是性能分析和调优的基本工具。 Kubernetes 也提供了类似的命令&#xff0c;就是 kubectl top&#xff0c;不过默认情况下这个命令不会生效&#xff0c;必须要安装一个插件 Metrics …

[图的搜索]5.图解狄克斯特拉算法及其代码演示

狄克斯特拉算法 与前面提到的贝尔曼-福特算法类似&#xff0c;狄克斯特拉&#xff08;Dijkstra&#xff09;算法也是求解最短路径问题的算法&#xff0c;使用它可以求得从起点到终点的路径中权重总和最小的那条路径路径。 图解 01 这里我们设A为起点、G为终点&#xff0c;来讲…

论文笔记:Image Anaimation经典论文-运动关键点模型(Monkey-Net)

Monkey-Net&#xff08;MOviNg KEYpoints&#xff09; paper: https://arxiv.org/pdf/1812.08861, CVPR 2019 code: https://github.com/AliaksandrSiarohin/monkey-net/tree/master 相关工作 视频生成演变过程&#xff1a; spatio-temporal network: 如基于GAN网络的生成模…

探索重庆耶非凡科技:揭秘其背后的技术实力与市场布局

重庆耶非凡科技有限公司&#xff0c;作为重庆当地一家知名的综合性服务型企业&#xff0c;近年来在多个领域取得了显著的成绩。其业务范围广泛&#xff0c;不仅涵盖了传统的行业服务&#xff0c;还积极探索并实践了一系列创新项目&#xff0c;其中最为引人注目的便是选品师项目…