【Unity】 HTFramework框架(五十三)使用 Addressables 可寻址系统

news2024/9/26 13:49:08

更新日期:2024年7月25日。
Github源码:[点我获取源码]
Gitee源码:[点我获取源码]

索引

  • Addressables 可寻址系统
  • 使用 Addressables 可寻址系统
    • 一、导入 Addressables
    • 二、切换到 Addressables 加载模式
    • 三、切换资源加载助手
    • 四、加载资源
    • 五、注意事项

Addressables 可寻址系统

Addressables可寻址系统是迄今为止最完善的Unity资源管理方案,对资源的加载、打包甚至是部署都实现了流水线式的封装。

所以,是时候将Addressables加入到框架的资源加载策略中了。

不过,针对一些小型的项目、小游戏等,我们依然建议使用Resource加载模式或AssetBundle加载模式,因为Addressables会带来一定的资源管理复杂度,会增加维护成本。

使用 Addressables 可寻址系统

在框架中使用Addressables将极其简单,甚至原来使用Resource加载模式或AssetBundle加载模式的代码都不需要做出任何修改,就能直接无缝切换到Addressables模式。

一、导入 Addressables

首先是从包管理器中导入Addressables包,目前框架支持的Addressables版本为1.20.01.30.0之间的任何版本(后续会根据Addressables的版本迭代实时跟进):

在这里插入图片描述

二、切换到 Addressables 加载模式

Resource资源管理器模块的加载模式切换为Addressables模式:

在这里插入图片描述

三、切换资源加载助手

加载模式切换为Addressables模式后,我们会看到一条红色的错误提示:

DefaultResourceHelper(缺省的资源加载助手)不支持使用 Addressables 模式!

所以我们必须要更换资源加载助手,更换为HT.Framework.AddressablesHelper

在这里插入图片描述

它即是缺省的资源加载助手(Addressables 模式)

四、加载资源

此时,我们即可按常规方式加载资源(Main.m_Resource.Load...),在外部调用上,ResourceAssetBundleAddressables三种模式可以没有任何区别。

我们举个例子,将HTFrameworkDemo中的Resource场景切换为Addressables模式。

其原本是使用的AssetBundle模式,旨在演示如何使用AssetBundle加载预制体、材质球、场景等资源。

首先,将加载模式资源管理器助手按上文描述的进行设置:

在这里插入图片描述

然后,将需要加载的资源标记为可寻址

在这里插入图片描述

再者,运行场景,所有资源就能正确加载了:

在这里插入图片描述

是不是极其简单?且能做到代码零修改的无缝切换!

而且,原来的AssetBundle模式使用的是单线加载策略,每一个资源加载时都可能会存在等待时间,也即是等待当前加载的线路完成:

在这里插入图片描述
Addressables模式不使用单线加载策略,所以在上上图中我们可以看到加载日志中是没有等待耗时这个参数的。

五、注意事项

我们回看Demo场景中加载资源的代码:

    /// <summary>
    /// 资源测试
    /// </summary>
    public class ResourceTest : MonoBehaviour
    {
        private SceneInfo _scene = new SceneInfo("scene", "Assets/HTFrameworkDemo/Script/Resource/TestScene.unity", "TestScene");
        private PrefabInfo _cube = new PrefabInfo("cube", "Assets/HTFrameworkDemo/Script/Resource/Cube.prefab", null);
        private PrefabInfo _capsule = new PrefabInfo("capsule", "Assets/HTFrameworkDemo/Script/Resource/Capsule.prefab", null);
        private PrefabInfo _sphere = new PrefabInfo("sphere", "Assets/HTFrameworkDemo/Script/Resource/Sphere.prefab", null);
        private AssetInfo _redMat = new AssetInfo("redmat", "Assets/HTFrameworkDemo/Script/Resource/Red.mat", null);
        private List<GameObject> _prefabs = new List<GameObject>();
        private Material _red;

        private void Awake()
        {
            Main.m_Resource.SetAssetBundlePath(Application.dataPath + "/HTFrameworkDemo/Script/Resource/AB/");
        }

        private void Start()
        {
            //加载三个预制体,他们关联的AB包会被自动加载
            Main.m_Resource.LoadPrefab(_cube, null, OnLoading, OnLoadDone);
            Main.m_Resource.LoadPrefab(_capsule, null, OnLoading, OnLoadDone);
            Main.m_Resource.LoadPrefab(_sphere, null, OnLoading, OnLoadDone);
        }

        private void OnGUI()
        {
            if (GUILayout.Button("全部替换为红色材质"))
            {
                StartCoroutine(LoadRedMat());
            }
            if (GUILayout.Button("加载TestScene场景"))
            {
                Main.m_Resource.LoadScene(_scene);
            }
            if (GUILayout.Button("卸载TestScene场景"))
            {
                Main.m_Resource.UnLoadScene(_scene);
            }
            if (GUILayout.Button("卸载所有场景"))
            {
                Main.m_Resource.UnLoadAllScene();
            }
        }
        
        /// <summary>
        /// 加载红色材质
        /// </summary>
        private IEnumerator LoadRedMat()
        {
            yield return null;

            //等待加载完成
            yield return Main.m_Resource.LoadAsset<Material>(_redMat, null, (mat) =>
            {
                Log.Info("加载红色材质完成!");
                _red = mat;
            });

            for (int i = 0; i < _prefabs.Count; i++)
            {
                _prefabs[i].GetComponent<MeshRenderer>().material = _red;
            }
        }

        private void OnLoadDone(GameObject arg)
        {
            Log.Info("加载完成:" + arg.name);

            arg.SetActive(true);
            arg.transform.position = Vector3.zero + new Vector3(0, 0, _prefabs.Count * 2);
            Main.m_Controller.SetLookPoint(arg.transform.position);
            _prefabs.Add(arg);
        }

        private void OnLoading(float arg)
        {
            Log.Info("加载中,进度:" + arg);
        }
    }

为了实现三种加载模式间的无缝切换,Addressables模式加载资源时建议依然传入完整的资源信息对象,比如:

PrefabInfo cube = new PrefabInfo("cube", "Assets/HTFrameworkDemo/Script/Resource/Cube.prefab", "Cube");
Main.m_Resource.LoadPrefab(_cube, null);

在这里,事实上Addressables只关心第二个参数assetPath,它是通过第二个参数去寻址资源的,改成下面这样也能正确加载:

PrefabInfo cube = new PrefabInfo(null, "Assets/HTFrameworkDemo/Script/Resource/Cube.prefab", null);
Main.m_Resource.LoadPrefab(_cube, null);

只不过,为了考虑无缝切换,第一个参数和第三个参数也建议正常传入。

还有就是,资源的寻址Key建议始终设置为其相对路径

在这里插入图片描述

这样可以应对大多数变化,且此相对路径永远都是唯一的。

还有一个重点,在缺省的HT.Framework.AddressablesHelper助手中,使用Main.m_Resource.Load...加载任何资源都不会产生引用计数,也即是资源的引用计数特性在这里是无效的,是不需要关心的,因为它有一定的管理复杂性,与我们的宗旨背道而驰(更简洁的代码、更简易的功能、依然能实现我们的需求)。

关于Addressables如何进行资源管理和配置,我这里就不做涉及了,看完下面这篇文章会使你醍醐灌顶:

【游戏开发探究】Unity Addressables资源管理方式。

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

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

相关文章

【全面介绍Python多线程】

🎥博主:程序员不想YY啊 💫CSDN优质创作者,CSDN实力新星,CSDN博客专家 🤗点赞🎈收藏⭐再看💫养成习惯 ✨希望本文对您有所裨益,如有不足之处,欢迎在评论区提出指正,让我们共同学习、交流进步! 🦇目录 1. 🦇前言2. 🦇threading 模块的基本用法3. 🦇Thre…

编程类精品GPTs

文章目录 编程类精品GPTs前言种类ChatGPT - GrimoireProfessional-coder-auto-programming 总结 编程类精品GPTs 前言 代码类的AI, 主要看以下要点: 面对含糊不清的需求是否能引导出完整的需求面对完整的需求是否能分步编写代码完成需求编写的代码是否具有可读性和可扩展性 …

【个人亲试最新】WSL2中的Ubuntu 22.04安装Docker

文章目录 Wsl2中的Ubuntu22.04安装Docker其他问题wsl中执行Ubuntu 报错&#xff1a;System has not been booted with systemd as init system (PID 1). Can‘t operate. 参考博客 &#x1f60a;点此到文末惊喜↩︎ Wsl2中的Ubuntu22.04安装Docker 确定为wsl2ubuntu22.04&#…

57 数据链路层

用于两个设备&#xff08;同一种数据链路节点&#xff09;之间传递 目录 对比理解“数据链路层” 和 “网络层”以太网 2.1 认识以太网 2.2 以太网帧格式MAC地址 3.1 认识MAC地址 3.2 对比理解MAC地址和IP地址局域网通信MTU 5.1 认识MTU 5.2 MTU对ip协议的影响 5.3 MTU对UDP的…

vue elementui 在table里使用el-switch

<el-table-columnprop"operationStatus"label"状态"header-align"center"align"center"><template slot-scope"scope"><el-switch active-value"ENABLE" inactive-value"DISABLE" v-mod…

Java OpenCV 图像处理40 图形图像 图片裁切ROI

Java OpenCV 图像处理40 图形图像 图片裁切 在 OpenCV 中&#xff0c;Rect 类是用来表示矩形的数据结构&#xff0c;通常用于定义图像处理中的感兴趣区域&#xff08;Region of Interest&#xff0c;ROI&#xff09;&#xff0c;或者指定图像中的某个区域的位置和大小。Rect 类…

【深度学习】大模型GLM-4-9B Chat ,微调与部署(3) TensorRT-LLM、TensorRT量化加速、Triton部署

文章目录 获取TensorRT-LLM代码&#xff1a;构建docker镜像并安装TensorRT-LLM&#xff1a;运行docker镜像&#xff1a;安装依赖魔改下部分package代码&#xff1a;量化&#xff1a;构建图&#xff1a;全局参数插件配置常用配置参数 测试推理是否可以代码推理CLI推理 性能测试小…

Python爬虫技术 第09节 状态码

在使用Python进行网络爬虫开发时&#xff0c;理解HTTP状态码是至关重要的。HTTP状态码是由服务器返回给客户端的响应状态指示&#xff0c;通常用于告知客户端请求是否成功、失败或需要采取进一步的操作。下面是一些常见的HTTP状态码及其含义&#xff1a; 常见的HTTP状态码 1xx…

Lua脚本简单理解

目录 1.安装 2.语法 2.1Lua数据类型 2.2变量 2.3lua循环 2.4流程控制 2.5函数 2.6运算符 2.7关系运算符 3.lua脚本在redis中的使用 3.1lua脚本再redis简单编写 3.2普通锁Lua脚本 3.3可重入锁lua脚本 1.安装 centos安装 安装指令&#xff1a; yum -y update yum i…

5. System Design 5.2. 身份验证框架和信任链

快速链接: . &#x1f449;&#x1f449;&#x1f449; 个人博客笔记导读目录(全部) &#x1f448;&#x1f448;&#x1f448; 付费专栏-付费课程 【购买须知】我的联系方式-自建交流群-学习群 【必看/必看&#xff01;&#xff01;】ATF架构开发精讲-专题目录&#x1f448;…

Unity Android接入SDK 遇到的问题

1. buildtools、platformtools、commandline tools 以及compiled sdk version、buildtools sdk version、target sdk version 的说明 Android targetSdkVersion了解一下 - 简书 2. 查看.class 和.jar文件 jd_gui 官网地址&#xff1a; 下载jd_gui 工具 &#xff0c;或者 idea 下…

全方位数据管理:一站式爬虫服务解决方案

摘要 面对互联网信息爆炸的时代&#xff0c;如何高效地收集、整理并分析海量数据&#xff0c;成为企业与开发者面临的一大挑战。本文将深入探讨一站式爬虫服务解决方案&#xff0c;揭示如何通过全方位数据管理策略&#xff0c;助力企业轻松驾驭大数据海洋&#xff0c;实现数据…

事务和函数索引

事务 事务的定义 事务&#xff08;Transaction&#xff09;&#xff0c;就是将一组SQL语句放在同一批次内去执行&#xff0c;如果一个SQL语句出错&#xff0c;则该批次内 的所有SQL都将被取消执行。 事务的特点 一个事务中如果有一个数据库操作失败&#xff0c;那么整个 事务…

光明乳业:以科技赋能品质,引领乳业绿色新未来

近日&#xff0c;光明乳业再次成为行业焦点&#xff0c;其在科技创新与绿色发展方面的卓越表现赢得了广泛赞誉。作为中国乳制品行业的领军企业&#xff0c;光明乳业始终坚守品质至上的原则&#xff0c;不断探索科技创新之路&#xff0c;致力于为消费者提供更高品质、更健康的乳…

芯片的计算能力由什么决定

芯片的计算能力由什么决定 芯片的计算能力由多个因素决定。 包括但不限于&#xff1a; 架构设计&#xff1a; 芯片的架构设计决定了其计算单元的数量和类型&#xff0c;以及它们之间的连接方式和通信方式。不同的架构可以提供不同的计算能力和性能。处理器速度&#xff1a; 处…

Linux下普通用户无法执行sudo指令

当执行sudo指令时出现&#xff1a; xxx&#xff08;普通用户名字&#xff09; is not in the sudoers file 说明在/etc/sudoers文件中没有把xxx加入到可执行sudo指令的名单中&#xff0c;因此需要修改sudoers文件。 解决方法&#xff1a;1、vim /etc/sudoers &#xff08;要…

【图像标签转换】XML转为TXT图像数据集标签

引言 该脚本用于将包含对象标注的 XML 文件转换为 YOLO&#xff08;You Only Look Once&#xff09;对象检测格式的 TXT 文件。脚本读取 XML 文件&#xff0c;提取对象信息&#xff0c;规范化边界框坐标&#xff0c;并将数据写入相应的 TXT 文件。此外&#xff0c;它还生成一个…

深度学习1-简介

人工智能&#xff08;AI&#xff09;旨在打造模仿智能行为的系统。它覆盖了众多方法&#xff0c;涵盖了基于逻辑、搜索和概率推理的技术。机器学习是 AI 的一个分支&#xff0c;它通过对观测数据进行数学模型拟合来学习决策制定。这个领域近年来迅猛发展&#xff0c;现在几乎&a…

谷粒商城实战笔记-64-商品服务-API-品牌管理-OSS前后联调测试上传

文章目录 1&#xff0c;拷贝文件到前端工程2&#xff0c;局部修改3&#xff0c;在品牌编辑界面使用上传组件4&#xff0c;OSS配置允许跨域5&#xff0c;测试multiUpload.vue完整代码singleUpload.vue完整代码policy.js代码 在Web应用开发中&#xff0c;文件上传是一项非常常见的…

基于PaddleClas的人物年龄分类项目

目录 一、任务概述 二、算法研发 2.1 下载数据集 2.2 数据集预处理 2.3 安装PaddleClas套件 2.4 算法训练 2.5 静态图导出 2.6 静态图推理 三、小结 一、任务概述 最近遇到个需求&#xff0c;需要将图像中的人物区分为成人和小孩&#xff0c;这是一个典型的二分类问题…