使用 Addressables 来管理资源

一、安装

打开Package Manager,在Unity Technologies的目录下找到Addressables,更新或下载。

二、配置

依次打开Windows/Asset Management/Addressables/Groups菜单。

首次打开后会提示需要创建配置文件,点击Create Addressables Settings

Assets目录下会生成AddressableAssetsData文件夹。

Ⅰ. 认识资源组(AssetGroups)与组策略(AssetGroups Schemas)概念

  1. 点击Manage Groups,返回刚才的Addressables Groups面板。此时已经有了两个内置的组。

  2. Built In Data存储的是工程中Resources文件夹下的资源,随App构建的场景资源,以及其他一些必要的资源等。

  3. Default Local Group (Default)组存储的是工程中被标记为Addressables的资源,假如不对其进行手动分组,则默认放在这个组中。

  4. 点击Create,可以指定模板来复制一个组或者创建一个全新的组。模板存储在AddressableAssetsData/AssetGroupTemplates文件夹下,默认有一个名为Packed Assets的模板,新创建的组存储在AddressableAssetsData/AssetGroups文件夹下。我们手动建立一个名为Remote的新组。

  5. 点击Remote组的Add Schema按钮,添加Content Update RestrictionContent Packing & Loading策略。注意不要额外添加Resources and Built In Scene策略,这个已经由Built In Data组负责了。

    AssetGroups文件夹中有一个Schemas文件夹,存放着所有资源组的组策略序列化文件,命名规则为$"{组名}_{策略类型}"

  6. 配置Remote组策略。

    • 修改在Content Update Restriction下的Update Restriction选项。

      Can Change Post Release的意思是,当前资源组进行最终构建时会完全覆盖上一次构建结果(打包出的文件名与上一次不同,上一次的包彻底无效化,部署时可以直接删掉),一般这种方式叫做 全量更新

      Can not Change Post Release则意味着,当前资源组构建时需要与上一次构建结果进行比对(Addressables Groups/Tools/Check for Content Update Restrictions),上一次构建出的包不发生变化,新构建的包则建立在旧包的基础上(相同的资源存储在旧包内,修改和添加的资源存储在新包内,部署时需要将新包和旧包一起发到服务器上),这种方式一般叫做 增量更新

    • 修改Content Packing & Loading下的Build PathLoad Path选项。

      • LocalBuildPath 本地构建路径,当App发布时,会将这个路径下的包拷贝到App的StreamingAssets里。

      • LocalLoadPath 本地加载路径,当App运行时,会从这个路径下读取资源包,一般也是在App的StreamingAssets里。

        Local___Path 说明这个组中的资源包会包含在App的安装包内。如果所有资源组都设置为Local,则这个App安装包是 全资源包 (全资源包一般是设置为Can not Change Post Release的)。

      • RemoteBuildPath 远程构建路径,当构建资源包后,需要将这个路径下的包拷贝到服务器上。

      • RemoteLoadPath 远程加载路径,当App运行时,会从这个地址下载catalog,并与本地catalog对比来判断是否需要更新资源。

      如果想对 全资源包 进行更新,可以点击Addressables Groups/Tools/Check for Content Update Restrictions,会自动生成差异化资源组,将这些资源组设置为远程并构建部署,则可以将App内包含的旧资源进行覆盖。

    • Advanced Options 是更精细化控制资源包构建与加载流程的选项,无特殊情况保持默认即可。需要注意的是Include in Build选项,可以控制当前资源包是否参与本次构建。

Ⅱ. 总体配置

AddressableAssetSettings负责整体配置资源包的构建参数。

设置资源包地址的Profiles

Profiles/Profiles In Use 控制了当前资源包路径设置。

我们刚才对资源包的路径进行了本地与远程的设置,但是并没有深入了解这些路径是如何拼接而成的。比如为什么本地资源包会在构建到StreamingAssets文件夹中呢。

点击Manage Profiles,弹出上图的Addressables Profiles面板,之前我们设置的本地路径与远程路径就是在这里定义的。总体上路径由固定的字符串、中括号与花括号组成,中括号内包含了发布时编辑器所确定下来的变量,比如运行平台等;花括号则包含了App运行时所获取的变量,也可以在代码内手动指定一个自定义的变量。

这就解释了为什么我们将资源包指定为Local___Path时,最终会存在于App的StreamingAssets文件夹中,是因为[UnityEngine.AddressableAssets.Addressables.BuildPath]这个地址就是编辑器发布App时所指定目录下的StreamingAssets文件夹地址,而{UnityEngine.AddressableAssets.Addressables.RuntimePath}这个地址则是App运行时的StreamingAssets文件夹地址。

我们也可以新建一个测试用的Profile和一个发布用的Profile,只需要把RemoteLoadPath中的http地址指向测试用服务器地址和正式版服务器地址即可。

设置是否需要远程更新

假如我们的App不需要进行远程资源加载和更新,则保持Content Updata/Build Remote Catalog不勾选即可,否则则需要将其勾选。

Disable Catalog Update on Startup则决定是否在App启动时自动更新catalog。

假如我们希望App启动时将所有的更新包先行下载下来,则可以将其勾选,并在代码中手动调用
Addressables.InitializeAsync()
Addressables.CheckForCatalogUpdates()
Addressables.UpdateCatalogs()
等方法,获取到需要更新的资源包列表,并对其依次进行手动更新。

假如我们希望在App运行中需要某个资源时才会去从远程下载,则可以保持其不勾选的默认状态。这种方式下Addressables系统会在App启动时自动调用上述的一系列方法将本地catalog与远程同步,但是并不会更新资源包。

三、资源管理

  1. 将资源导入工程中

  2. 此时Inspector面板上新添加了一个Addressable选项。

    将需要打包的资源勾选,出现一长串的资源路径,这个路径就是我们加载这个资源时所需要的路径参数

  3. 点击Select按钮,弹出资源组面板,刚添加的资源会位于默认组员组Default Local Group (Default)中。

  4. 如果能保证不冲突的话,我们也可以将这个路径手动简化,或者让编辑器自动对其进行简化。在资源组面板右键资源并点击Simplify Addressable Names,可以将复杂的路径简化为不带类型后缀的文件名,方便使用。

  5. 也可以为资源指定标签。将一系列资源指定为同一个标签后,则可以在App运行时将其以按标签加载的方式同时加载进来。比如我们将工程中的Lua脚本全部指定一个Scripts的标签等。

四、构建资源包

Ⅰ. 首次构建

首次构建资源包需要点击资源组面板的Build/New Build/Default Build Script

打包成功后在AddressableAssetsData文件夹下生成一个保存当前资源状态的bin文件,这个文件是后续资源增删改时用来与前一次打包做对比用的,并且它保存了至关重要的catalog文件信息。

同时在RemoteBuildPath位置生成catalog以及远程资源包。

此时我们可以随即进行App的构建。

每次构建资源包,都需要重新构建App。

如果希望更新资源包,不能使用Build/New Build方式。

Ⅱ. 更新包

将资源增删改完毕之后,点击Tools/Check for Content Update Restrictions

选择首次构建时生成的bin文件,弹出Content Update Preview面板,点击Apply Changes

我们这里的默认资源组的Content Update Restriction选项设置的是Can not Change Post Release,因为本地资源已经跟随App一同发布了,修改本地资源是没有意义的,除非重新构建App。

编辑器替我们自动生成了新的远程资源组,并将有变动的资源放了进去。

这里不要混淆 远程资源组Content Update Restriction 两个概念,远程资源组既可以标记为不可修改,也可以标记为可修改。

我们可以把这些资源放到其他远程组里,也可以保持不变,这方面的策略应该顾及资源包的粒度,文件大小等,严格执行起来还是比较烧脑的。

资源组重新设定完毕后,点击Build/Update a Previous Build,并再次选择首次构建时生成的bin文件,以更新方式构建资源包。

切勿以Build/New Build的方式构建,如果不小心点了,两个解决方式,git reset --hard或者重新打包App……

此时打开远程构建目录(RemoteBuildPath),发现已经生成了由新的远程资源组构建的资源包,而catalog文件的修改日期也已经发生了变化,说明虽然catalog文件名没有发生变化,但是其内容已经更新了。

我这里截图的catalog文件名发生了变化,是写文测试的时候把之前的构建结果给删了,实际上应该是不会发生变化的,请忽略。o_0

我们允许的流程是:构建资源包->构建App->以更新方式构建资源包->以更新方式构建资源包...

我们不允许的流程是:...->构建App->构建资源包...

原因是每次点击Build/New Build/***,catalog文件名都会发生变化,而App只记录上一次构建资源包时的catalog文件名,假如我们在构建App之后重新构建了资源包,则旧的App无法识别新的catalog,从而更新失败。

五、部署

RemoteBuildPath目录下的文件上传至服务器,包括资源包以及catalog文件,保证RemoteLoadPath可访问即可。

实际部署还是比教程写的要麻烦很多的。权限,跨域,负载能力,加密,防止各种网络攻击等,各种手段都要用上。我们仅仅是验证技术路线,麻烦事就先不考虑啦。

如果仅仅是测试的话,其实编辑器还提供了一个Host功能

点击Create/LocalHosting,新建一个服务端,指定端口,勾选Enable即可。

注意我们需要将Profiles/RemoteLoadPath修改为http://本机IP或者localhost:端口号,默认Profiles的远程加载地址多了一个[BuildTarget],这是访问不到的。

六、加载

新建一个脚本,用来测试资源的加载。

using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.ResourceManagement.AsyncOperations;
using UnityEngine.UI; public class SwitchSprites : MonoBehaviour
{
[SerializeField] private RawImage _emojiImage;
[SerializeField] private Text _infoText; private int _indicator; private AsyncOperationHandle<IList<Texture>> _operation; private async void Start()
{
_operation = Addressables.LoadAssetsAsync<Texture>("emoji", null);
await _operation.Task; _infoText.text = "Emoji Load Completed"; GetComponent<Button>().onClick.AddListener(() =>
{
_indicator++;
if (_indicator >= _operation.Result.Count)
{
_indicator = 0;
} _emojiImage.texture = _operation.Result[_indicator];
});
} private void OnDestroy()
{
Addressables.Release(_operation);
}
}

这里一上来直接就可以Addressables.LoadAssetsAsync<Texture>(),是因为我测试的时候没有勾选AddressableAssetSettings/Content Update /Disable Catalog Update on Startup,所以App在加载时自动更新了catalog,而资源包下载则类似于Lazy 模式,即用即下载(缓存中如果有匹配的资源包则直接加载)。真正使用这套系统时,一般会采用勤快一点的模式,先更新必要的资源包,读条一波,然后App才正式运行。

使用 Addressables 来管理资源的更多相关文章

  1. 基于EasyUI Treegrid的权限管理资源列表

    1. 前言 最近在开发系统权限管理相关的功能,主要包含用户管理,资源管理,角色管理,组类别管理等小的模块.之前的Web开发中也用过jQueryEasyUI插件,感觉这款插件简单易用,上手很快.以前用到 ...

  2. EC笔记:第三部分:13、以对象管理资源

    C++相比Java等含有gc的语言来说,内存管理方面(也包括资源管理)比较令人头疼.一些初级程序员,甚至是一些经验丰富的老程序员,也会经常在资源管理上犯错.这时候就需要一个能够自动管理资源的东西(gc ...

  3. spring security动态管理资源结合自定义登录页面

    如果想将动态管理资源与自定义登录页面一起使用,最简单的办法就是在数据库中将登录页面对应的权限设置为IS_AUTHENTICATED_ANONYMOUSLY. 因此在数据库中添加一条资源信息. INSE ...

  4. Effective C++ ----以对象管理资源

    以对象管理资源 通过对象的析构函数的自动调用来自动释放资源 第一部分:几种典型的以对象管理资源的例子 1. STL::auto_ptr 获取资源后立刻放入资源管理对象 std::auto_ptr< ...

  5. [Effective C++ --013]以对象管理资源

    这一节基本讲述的是将资源放进管理对象,防止忘记释放资源. 1.一般New和Delete使用场景 void fun() { SimpleClass* pSimpleClass1 = new Simple ...

  6. 《Effective C++》学习笔记条款13 以对象管理资源

    条款 13 :以对象管理资源 例:      voidf()      {           Investment *pInv = createInvestment();           ... ...

  7. 以对象管理资源——C++智能指针auto_ptr简介

    auto_ptr是C++标准库提供的类模板,它可以帮助程序员自动管理用new表达式动态分配的单个对象.auto_ptr对象被初始化为指向由new表达式创建的对象,当auto_ptr对象的生命期结束时, ...

  8. 第十九章——使用资源调控器管理资源(1)——使用SQLServer Management Studio 配置资源调控器

    原文:第十九章--使用资源调控器管理资源(1)--使用SQLServer Management Studio 配置资源调控器 本系列包含: 1. 使用SQLServer Management Stud ...

  9. 第十九章——使用资源调控器管理资源(2)——使用T-SQL配置资源调控器

    原文:第十九章--使用资源调控器管理资源(2)--使用T-SQL配置资源调控器 前言: 在前一章已经演示了如何使用SSMS来配置资源调控器.但是作为DBA,总有需要写脚本的时候,因为它可以重用及扩展. ...

随机推荐

  1. Ubuntu virtualenv 创建 python3 虚拟环境 激活 退出

    首先默认安装了virtualenv 创建python3虚拟环境 your-name@node-name:~/virtual_env$ virtualenv -p /usr/bin/python3 py ...

  2. Centos7上安装Ubuntu容器

    1.再次之前我们要先装好docker,在上一篇我已经给出了教程,没有安装好的快去看看吧! 2.这里我们使用的是linux系统,所有在线安装是最简便的方法了.我们可以从国内拉取dockerhub镜像,这 ...

  3. sudo 命令详解

    在linux系统中,由于root的权限过大,一般情况都不使用它.只有在一些特殊情况下才采用登录root执行管理任务,一般情况下临时使用root权限多采用su和sudo命令. 一.su和sudo命令对比 ...

  4. Git使用教程之初级入门命令行(二)

    一.Git 操作流程图 1.git --help 查看帮助 Administrator@PC-xiaobing MINGW64 /d/Git (master) $ git --help usage: ...

  5. log4j日志集成

    一.介绍  Log4j是Apache的一个开放源代码项目,通过使用Log4j,我们可以控制日志信息输送的目的地是控制台.文件.GUI组件.甚至是套接口服务 器.NT的事件记录器.UNIX Syslog ...

  6. vue配置请求拦截器和响应拦截器

    首先确保我们已经设置的store.js进行值的存取,这时候我们需要配置请求和响应的拦截器设置 main.js import Vue from 'vue' import App from './App' ...

  7. FZU_DS_2019_SequenceList

    单选题 2-1   数组A[1..5,1..6]每个元素占5个单元,将其按行优先次序存储在起始地址为1000的连续的内存单元中,则元素A[5,5]的地址为:  A.1120      B.1125   ...

  8. 从零开始制作一个linux iso镜像

    一.前言     对于一个极简化的linux系统而言,只需要三个部分就能组成,它们分别是一个linux内核.一个根文件系统和引导.以下是本文制作linux iso镜像所用到的系统和软件:     OS ...

  9. 大爽Python入门教程 1-1 简单的数学运算

    大爽Python入门公开课教案 点击查看教程总目录 1 使用pycharm建立我们的第一个项目 打开pycharm,点击菜单栏,File->New Project 在Location(项目地址) ...

  10. 菜鸡的Java笔记

    1.注释 在JAVA中对于注释有三种: 单行注释:// 多行注释:/*--*/ 文档注释:/**--*/ 2.关键字和标识符 在程序中描述类名称,方法名称,变量等概念就需要使用标识符来定义.而在JAV ...