18.自定义更新目录和下载AB包

18.其他_资源加载相关_自定义更新目录和下载AB包


18.1 知识点

目录的作用

目录文件的本质是Json文件和一个Hash文件。
其中记录的主要内容有:

Json文件中记录的是:

  • 加载AB包、图集、资源、场景、实例化对象所用的脚本(会通过反射去加载他们来使用)。
  • AB包中所有资源类型对应的类(会通过反射去加载他们来使用)。
  • AB包对应路径。
  • 资源的path名等。

Hash文件中记录的是:

  • 目录文件对应hash码(每一个文件都有一个唯一码,用来判断文件是否变化)。
  • 更新时本地的文件hash码会和远端目录的hash码进行对比。
  • 如果发现不一样就会更新目录文件。

当我们使用远端发布内容时,在资源服务器也会有一个目录文件。Addressables会在运行时自动管理目录。如果远端目录发生变化了(他会通过hash文件里面存储的数据判断是否是新目录),它会自动下载新版本并将其加载到内存中。

手动更新目录

如果要手动更新目录,建议在AddressableAssetSettings设置中勾选DisableCatalogUpdateOnSartup,关闭自动更新。

Addressables.UpdateCatalogs 自动检查所有目录是否有更新,并更新目录

//更新完可以把目录handle释放了
Addressables.UpdateCatalogs().Completed += (handle) => { Addressables.Release(handle); };

Addressables.CheckForCatalogUpdates 获取目录列表,再更新目录

//参数是bool类型的autoReleaseHandle  就是加载结束后 会不会自动释放异步加载的句柄 默认是true
Addressables.CheckForCatalogUpdates(true).Completed += (checkForCatalogUpdatesHandle) =>
{
    //如果列表里面的内容大于0 证明有可以更新的目录
    if (checkForCatalogUpdatesHandle.Result.Count > 0)
    {
        //根据目录列表更新目录
        Addressables.UpdateCatalogs(checkForCatalogUpdatesHandle.Result, true).Completed += (updateCatalogsHandle) =>
        {
            //如果更新完毕 记得释放资源 上面autoReleaseHandle是true的话就不用自己写释放
            //Addressables.Release(updateCatalogsHandle);
            //Addressables.Release(checkForCatalogUpdatesHandle);
        };
    }
};

预加载包

建议通过协程来加载。

Addressables.GetDownloadSizeAsync 首先获取下载包的大小

Addressables.DownloadDependenciesAsync 异步加载所有依赖的AB包相关内容了

IEnumerator LoadAssetCoroutine()
{
    //1.Addressables.GetDownloadSizeAsync 首先获取下载包的大小
    //可以传资源名、标签名、或者两者的组合
    AsyncOperationHandle<long> handleSize =
        Addressables.GetDownloadSizeAsync(new List<string>() { "Cube", "Sphere", "SD" });
    yield return handleSize;

    //2.预加载
    if (handleSize.Result > 0)
    {
        //Addressables.DownloadDependenciesAsync 异步加载所有依赖的AB包相关内容了
        AsyncOperationHandle asyncOperationHandle =
            Addressables.DownloadDependenciesAsync(new List<string>() { "Cube", "Sphere", "SD" },
                Addressables.MergeMode.Union);
        
        while (!asyncOperationHandle.IsDone)
        {
            //3.加载进度
            DownloadStatus downloadStatus = asyncOperationHandle.GetDownloadStatus();
            print(downloadStatus.Percent);
            print(downloadStatus.DownloadedBytes + "/" + downloadStatus.TotalBytes);
            yield return 0;
        }

        Addressables.Release(asyncOperationHandle);
    }
}
StartCoroutine(LoadAssetCoroutine());

总结

一般我们会在刚进入游戏时或者切换场景时显示一个Loading界面。我们可以在此时提前加载包,这样之后在使用资源就不会出现明显的异步加载延迟感。目录更新我们一般都会放在进入游戏开始游戏之前。


18.2 知识点代码

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

public class Lesson18_其他_资源加载相关_自定义更新目录和下载AB包 : MonoBehaviour
{
    void Start()
    {
        #region 知识点一 目录的作用

        //目录文件的本质是Json文件和一个Hash文件
        //其中记录的主要内容有

        //Json文件中记录的是:
        //1.加载AB包、图集、资源、场景、实例化对象所用的脚本(会通过反射去加载他们来使用)
        //2.AB包中所有资源类型对应的类(会通过反射去加载他们来使用)
        //3.AB包对应路径
        //4.资源的path名
        //等等

        //Hash文件中记录的是:
        //目录文件对应hash码(每一个文件都有一个唯一码,用来判断文件是否变化)
        //更新时本地的文件hash码会和远端目录的hash码进行对比
        //如果发现不一样就会更新目录文件

        //当我们使用远端发布内容时,在资源服务器也会有一个目录文件
        //Addressables会在运行时自动管理目录
        //如果远端目录发生变化了(他会通过hash文件里面存储的数据判断是否是新目录)
        //它会自动下载新版本并将其加载到内存中

        #endregion

        #region 知识点二 手动更新目录

        //1.如果要手动更新目录 建议在AddressableAssetSettings设置中勾选DisableCatalogUpdateOnSartup,关闭自动更新

        //2. Addressables.UpdateCatalogs 自动检查所有目录是否有更新,并更新目录 
        //更新完可以把目录handle释放了
        Addressables.UpdateCatalogs().Completed += (handle) => { Addressables.Release(handle); };

        //3.Addressables.CheckForCatalogUpdates 获取目录列表,再更新目录
        //参数是bool类型的autoReleaseHandle  就是加载结束后 会不会自动释放异步加载的句柄 默认是true
        Addressables.CheckForCatalogUpdates(true).Completed += (checkForCatalogUpdatesHandle) =>
        {
            //如果列表里面的内容大于0 证明有可以更新的目录
            if (checkForCatalogUpdatesHandle.Result.Count > 0)
            {
                //根据目录列表更新目录
                Addressables.UpdateCatalogs(checkForCatalogUpdatesHandle.Result, true).Completed += (updateCatalogsHandle) =>
                {
                    //如果更新完毕 记得释放资源 上面autoReleaseHandle是true的话就不用自己写释放
                    //Addressables.Release(updateCatalogsHandle);
                    //Addressables.Release(checkForCatalogUpdatesHandle);
                };
            }
        };

        #endregion

        #region 知识点三 预加载包

        //建议通过协程来加载
        StartCoroutine(LoadAssetCoroutine());

        //1.首先获取下载包的大小

        //2.预加载

        //3.加载进度

        #endregion

        #region 总结

        //一般我们会在
        //刚进入游戏时 或者 切换场景时 显示一个Loading界面
        //我们可以在此时提前加载包,这样之后在使用资源就不会出现明显的异步加载延迟感
        //目录更新 我们一般都会放在进入游戏开始游戏之前

        #endregion
    }


    IEnumerator LoadAssetCoroutine()
    {
        //1.Addressables.GetDownloadSizeAsync 首先获取下载包的大小
        //可以传资源名、标签名、或者两者的组合
        AsyncOperationHandle<long> handleSize =
            Addressables.GetDownloadSizeAsync(new List<string>() { "Cube", "Sphere", "SD" });
        yield return handleSize;

        //2.预加载
        if (handleSize.Result > 0)
        {
            //Addressables.DownloadDependenciesAsync 异步加载所有依赖的AB包相关内容了
            AsyncOperationHandle asyncOperationHandle =
                Addressables.DownloadDependenciesAsync(new List<string>() { "Cube", "Sphere", "SD" },
                    Addressables.MergeMode.Union);
            
            while (!asyncOperationHandle.IsDone)
            {
                //3.加载进度
                DownloadStatus downloadStatus = asyncOperationHandle.GetDownloadStatus();
                print(downloadStatus.Percent);
                print(downloadStatus.DownloadedBytes + "/" + downloadStatus.TotalBytes);
                yield return 0;
            }

            Addressables.Release(asyncOperationHandle);
        }
    }
}


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com

×

喜欢就点赞,疼爱就打赏