Addressables学习笔记3: 实际操作实现资源热更新

本篇基本上是官方演示的东西,介绍一下如何快速使用Addressables实现资源热更。为了能够热更资源,你需要有一个资源服务器使你能下载资源。

 

一、资源准备

首先打开Unity编辑器菜单 -> Window -> Asset Management -> Addressable Assets。最好将它固定到Editor里面,便于随时操作。然后随便制作一个prefab备用。

将该prefab拖拽到Addressables窗口的"Default Local Group"组中,结果如下图:

Addressables学习笔记3: 实际操作实现资源热更新_第1张图片

为了便于载入,使用如图的右键菜单项将其名字进行简化,它变成了成 "MyRemotePrefab"。

Addressables学习笔记3: 实际操作实现资源热更新_第2张图片

左键点击以选中 "Default Local Group"这个条目,在其Inspector窗口中我们可以看到其各种Schema的属性:

Addressables学习笔记3: 实际操作实现资源热更新_第3张图片

要保证这个Group中一定有BundledAssetGroupSchema与ContentUpdateGroupSchema,其中的资源才能正常被热更。按如下的方式设置各种属性:

1.将ContentUpdateGroupSchema中的StaticContent设置为false;

2.将BundledAssetGroupSchema中的BuildPath选中为 "RemoteBuildPath";

3.将BundledAssetGroupSchema中的LoadPath选中为"RemoteLoadPath";

4.检查AssetBundleProviderType,确认其值是 AssetBundleProvider;

5.此时它的LoadPath应该还不是你实际上的资源服上的路径。选中Project面板中的 Assets/AddressableAssetsData/AddressableAssetSettings, 在"Profiles"这一节,编辑ProfileEntries中的RemoteLoadPath条目,改成你的资源服务器地址:

Addressables学习笔记3: 实际操作实现资源热更新_第4张图片

如果想要修改其他条目的路径,也可以一并修改。

 

二、准备测试场景

创建一个MonoBehaviour,名为LoadPrefab,代码如下:

using UnityEngine;
using UnityEngine.AddressableAssets;

public class LoadPrefab : MonoBehaviour
{
    public string address;
    // Start is called before the first frame update
    void Start()
    {
        Load();
    }

    void Load()
    {
        Addressables.LoadAsset(address).Completed +=
            (op) =>
            {
                if (op.Status == UnityEngine.ResourceManagement.AsyncOperationStatus.Succeeded)
                {
                    Debug.Log(op.Result as GameObject);
                    var go = Instantiate(op.Result as GameObject, Vector3.zero, Quaternion.identity, transform);
                    go.transform.localPosition = Vector3.zero;
                }
            };
    }
}

在场景中创建一个空的GameObject,然后将该MonoBehaviour添加到它上面。由于我创建的是一个UI,因此我创建了一个Canvas而不是空的GO.

我们将该Component中的Address修改为 MyRemotePrefab ,使之能被载入。

 

三、添加日志输出

这部分只是为了查看日志,可以直接跳过。

1.在Assets文件夹中创建一个文本文件,改名为 csc.rsp。该文本文件中的内容为 "-define:ADDRESSABLES_LOG_ALL"(不包括引号)。其作用是让Addressables输出的日志更详细。

2.在Packages(注意它不在Assets这个文件夹中)中找到Addressables System,选中它其中任意一个cs文件,然后Reimport之。这是为了让Unity重新编译以使第1步创建的 预编译指令文件生效。

 

四、打包

在Addressables窗口中,点击Build菜单执行"Build Player Content"操作:

Addressables学习笔记3: 实际操作实现资源热更新_第5张图片

然后将RemoteBuildPath(如果没有修改过,它应该是 ProjectDir/ServerData/StandaloneWindows64)中生成的文件全部上传到你的资源服务器对应路径中。

最后,打一个游戏包出来。

 运行之后,可以看到在稍微等待零点几秒后,加载出了对应的Prefab(一个UI界面):

Addressables学习笔记3: 实际操作实现资源热更新_第6张图片

哦豁,由于我忘了给右上角的文本添加锚点,导致它显示不全。

 

五、热更新

将原有的UI进行修改,给文本添加了锚点并将它们移到右上角,更换了背景图片的颜色。

然后,我们要使用Addressables窗口的Build/Build For Content Update来进行更新资源的打包。

Addressables学习笔记3: 实际操作实现资源热更新_第7张图片

结果它弹出了一个文件选择窗口,让我们选择 Build Data File。这个文件实际上是上次打包时生成的、用于记录那时候资源相关的各种状态数据的一个文件。它存放在 ProjectDir/Library/com.unity.addressables 这个文件夹之中。

我们选中addressables_content_state.bin 这个文件,点击 "打开(O)"按钮以确定。

之后Unity进行打包,完成后可以看到在 RemoteBuildPath文件夹下已经生成了新的文件:

Addressables学习笔记3: 实际操作实现资源热更新_第8张图片

我们将这些新文件上传到资源服务器,然后重新启动程序,可以看到锚点问题已经修正了,背景颜色也已被修改,说明我们已经用新的prefab替换掉了老的:

Addressables学习笔记3: 实际操作实现资源热更新_第9张图片

 

六、一些细节问题

1.一般来说,我们是想要将资源先放在StreamingAssets中,等到发现有问题了才进行热更。但是如果你的所有Group都是本地的,Addresssables将不会尝试到服务器上下载最新的数据,也就无法进行资源更新了。因此这里只能一开始就将资源弄成Remote的。

2.Unity更新该资源的过程,简单来说就是:

  首先,实际上所有的Address都有一个对应的实际路径,通过加载时传入的Address,它经过一系列操作将它转换为一个实际地址,然后从该地址加载得到对应的对象。对于默认的情况,这个Address与实际路径对应的表是一个叫做catalog的JSON文件。

  如果你的资源需要更新,则"Build For Content Update"之后,你将得到与原先同名但是已被修改过的catalog文件,然后你将该catalog文件(以及其他文件)上传到服务器上。

  程序启动后,将首先加载catalog表。而实际上此时本地的catalog表已经是过时的了。程序如何知道它本地的catalog是过时的呢?

  对于每一个Group,如果它上面有BundledAssetGroupSchema,则你可以看到其中有一个属性是"Content Catalog Load Order",默认是0。其注释说

 ///The order in which the content catalog from this group will be loaded.  Usually remote catalogs are tried first and would have a lower value.  If this value is less than 0, no catalog will be generated.

  好像比较费解。经过实际测试,看起来是这么回事:由于每个Group都可以对应一套加载路径,那么catalog的加载路径究竟使用哪个Group的LoadPath呢?这个Order就指定了尝试的次序。它将从该值为0的Group之LoadPath开始尝试,如果加载不成功就去找Order为1的……(存疑,也可能是这样的逻辑:按照加载的次序,依次加载每个catalog,并且合并加载出的所有内容)在加载catalog的时候,它会先比较该catalog的hash值与Application.persistentData中保存的catalog.hash值,如果不一致则说明该catalog较本地缓存中的要新,则使用这个版本并且将hash和json文件都保存到本地缓存中;否则就直接使用本地缓存中的数据。关于这个尝试列表,它是存放在 StreamingAssets/com.unity.addressables/settings.json 这个文件中的。

  由于catalog已被更新,因此实际加载的时候,程序就能知道本地的资源已经过期,将自动去指定的资源服务器上下载并得到对应的新内容。

3.这个Addressables系统扩展性是很高的,熟悉了之后可以玩出很多花样;比起自己从Unity原有的资源加载与管理方式基础上弄一整套资源管理系统,Unity官方的方案应该是更稳定、扩展性更高、适用性更广的。当然现在不管是文档还是功能都不太完善,要实际应用还可以稍微等等。据论坛官方人员说,将在数周内放出一个示例项目,希望到时候能看到完整的、有趣的应用。

 

接下来应该是详细地看一看它的实现代码,把细节弄清楚,然后看怎样去进行自己的扩展。

转载于:https://www.cnblogs.com/thpGames/p/10361949.html

你可能感兴趣的:(Addressables学习笔记3: 实际操作实现资源热更新)