天天看点

使用 Addressables 来管理资源

Unity Addressables 资源管理

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

使用 Addressables 来管理资源

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

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

使用 Addressables 来管理资源

<code>Assets</code>目录下会生成<code>AddressableAssetsData</code>文件夹。

使用 Addressables 来管理资源

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

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

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

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

使用 Addressables 来管理资源

点击<code>Remote</code>组的<code>Add Schema</code>按钮,添加<code>Content Update Restriction</code>和<code>Content Packing &amp; Loading</code>策略。注意不要额外添加<code>Resources and Built In Scene</code>策略,这个已经由<code>Built In Data</code>组负责了。

在<code>AssetGroups</code>文件夹中有一个<code>Schemas</code>文件夹,存放着所有资源组的组策略序列化文件,命名规则为<code>$"{组名}_{策略类型}"</code>。
使用 Addressables 来管理资源

配置<code>Remote</code>组策略。

修改在<code>Content Update Restriction</code>下的<code>Update Restriction</code>选项。

<code>Can Change Post Release</code>的意思是,当前资源组进行最终构建时会完全覆盖上一次构建结果(打包出的文件名与上一次不同,上一次的包彻底无效化,部署时可以直接删掉),一般这种方式叫做 全量更新
而<code>Can not Change Post Release</code>则意味着,当前资源组构建时需要与上一次构建结果进行比对(<code>Addressables Groups/Tools/Check for Content Update Restrictions</code>),上一次构建出的包不发生变化,新构建的包则建立在旧包的基础上(相同的资源存储在旧包内,修改和添加的资源存储在新包内,部署时需要将新包和旧包一起发到服务器上),这种方式一般叫做 增量更新。

修改<code>Content Packing &amp; Loading</code>下的<code>Build Path</code>和<code>Load Path</code>选项。

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

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

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

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

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

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

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

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

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

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

使用 Addressables 来管理资源

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

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

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

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

使用 Addressables 来管理资源

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

假如我们希望App启动时将所有的更新包先行下载下来,则可以将其勾选,并在代码中手动调用

<code>Addressables.InitializeAsync()</code>、

<code>Addressables.CheckForCatalogUpdates()</code>、

<code>Addressables.UpdateCatalogs()</code>

等方法,获取到需要更新的资源包列表,并对其依次进行手动更新。

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

将资源导入工程中

此时<code>Inspector</code>面板上新添加了一个<code>Addressable</code>选项。

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

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

使用 Addressables 来管理资源

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

使用 Addressables 来管理资源

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

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

使用 Addressables 来管理资源

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

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

使用 Addressables 来管理资源

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

每次构建资源包,都需要重新构建App。 如果希望更新资源包,不能使用<code>Build/New Build</code>方式。

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

使用 Addressables 来管理资源

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

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

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

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

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

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

切勿以<code>Build/New Build</code>的方式构建,如果不小心点了,两个解决方式,<code>git reset --hard</code>或者重新打包App……
使用 Addressables 来管理资源

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

我这里截图的catalog文件名发生了变化,是写文测试的时候把之前的构建结果给删了,实际上应该是不会发生变化的,请忽略。o_0
使用 Addressables 来管理资源
我们允许的流程是:构建资源包-&gt;构建App-&gt;以更新方式构建资源包-&gt;以更新方式构建资源包... 我们不允许的流程是:...-&gt;构建App-&gt;构建资源包... 原因是每次点击<code>Build/New Build/***</code>,catalog文件名都会发生变化,而App只记录上一次构建资源包时的catalog文件名,假如我们在构建App之后重新构建了资源包,则旧的App无法识别新的catalog,从而更新失败。

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

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

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

使用 Addressables 来管理资源

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

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

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

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

继续阅读