安静如鸡

  • Home
  • About Me
  • Contact Me
  • 东京女子篮球活动记录
一个博客
  1. 首页
  2. Tech
  3. 正文

【Unity小贴士】关于Addressable的热更新

2023-09-29 0人点赞 0条评论

本篇会比较乱,边写边整理思路。

起因是用户说用LoadResourceLocationsAsync 一个Key获取到了两个同样的location,经查后,原因是在LoadResourceLocation之前调用了LoadContentCatalogAsync把远程的catalog导入,导致catalog重复了。(由于用户用的是Editor模式,不确定是否是本地的catalog和远程的重复还是单纯的导入远程catalog两次)

其实Unity关于热更新有一套方案,文档里面已经写的比较详细,但是文档里只写了要怎么做,没有写不可以怎么做(当然,哪个文档都不会这么写)所以用户可能误解了读取远程catalog需要用API手动读取。
https://docs.unity3d.com/Packages/com.unity.addressables@1.20/manual/RemoteContentDistribution.html

因为不太确定到底是怎么回事,查阅了很多内部外部资料,发现关于catalog说的都很模糊,但是文档里几乎是很明确的说,catalog的管理是自动管理的

By default, the Addressables system manages the catalog automatically at runtime. If you built your application with a remote catalog, the Addressables system automatically checks to see if you have uploaded a new catalog, and, if so, downloads the new version and loads it into memory.

那么问题来了,catalog到底是怎么自动从remote下载的?

首先assetbundle在打包的时候,本地会生成一个catalog和一个settings.json,在../Library/com.unity.addressables/aa/OSX/下面。这两个文件会跟着项目一起打包到app放在用户端里。下面是settings.json的主要内容,记录了hash位置,和本地catalog的位置。m_InternalId是在AddressableAssetSettings里设定的LoadPath

{
    "m_buildTarget": "StandaloneOSX",
    "m_SettingsHash": "",
    "m_CatalogLocations": [
        {
            "m_Keys": [
                "AddressablesMainContentCatalogRemoteHash"
            ],
            "m_InternalId": "http://192.168.12.8:59068/catalog_2020.05.03.19.43.34.hash",
            "m_Provider": "UnityEngine.ResourceManagement.ResourceProviders.TextDataProvider",
            "m_Dependencies": [],
            "m_ResourceType": {
                "m_AssemblyName": "mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089",
                "m_ClassName": "System.String"
            }
        },
        {
            "m_Keys": [
                "AddressablesMainContentCatalogCacheHash"
            ],
            "m_InternalId": "{UnityEngine.Application.persistentDataPath}/com.unity.addressables/catalog_2020.05.03.19.43.34.hash",
            "m_Provider": "UnityEngine.ResourceManagement.ResourceProviders.TextDataProvider",
            "m_Dependencies": [],
            "m_ResourceType": {
                "m_AssemblyName": "mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089",
                "m_ClassName": "System.String"
            }
        },
        {
            "m_Keys": [
                "AddressablesMainContentCatalog"
            ],
            "m_InternalId": "{UnityEngine.AddressableAssets.Addressables.RuntimePath}/catalog.json",
            "m_Provider": "UnityEngine.AddressableAssets.ResourceProviders.ContentCatalogProvider",
            "m_Dependencies": [
                "AddressablesMainContentCatalogRemoteHash",
                "AddressablesMainContentCatalogCacheHash"
            ],
            "m_ResourceType": {
                "m_AssemblyName": "Unity.Addressables, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null",
                "m_ClassName": "UnityEngine.AddressableAssets.ResourceLocators.ContentCatalogData"
            }
        }
    ],
    "m_ProfileEvents": false,
    "m_LogResourceManagerExceptions": true,
    "m_ExtraInitializationData": [],
    "m_CertificateHandlerType": {
        "m_AssemblyName": "",
        "m_ClassName": ""
JSON

然后在Addressable第一次被使用到的时候,会进行初始化,在初始化的InitializationOperation里面,会读取settings.json在里面有本地catalog的位置和Remote的catalog hash的位置。

读取后,在InitializationOperation的Excute里面会执行LoadContentCatalog这里ContentCatalogProvider的Start会被叫到,然后在里面的DetermineIdToLoad函数会做一个hash的判断,比较本地的catalog的hash和remote的hash是否相同,如果不相同则直接从同样位置下载catalog.json文件。从而达到自动下载更新catalog的目的。

const string kCatalogExt =
#if ENABLE_BINARY_CATALOG
            ".bin";
#else
            ".json";
#endif

            internal string DetermineIdToLoad(IResourceLocation location, IList<object> dependencyObjects, bool disableCatalogUpdateOnStart = false)
            {
                //default to load actual local source catalog
                string idToLoad = GetTransformedInternalId(location);
                if (.......)
                {
                    var remoteHash = dependencyObjects[(int)DependencyHashIndex.Remote] as string;
                    m_LocalHashValue = dependencyObjects[(int)DependencyHashIndex.Cache] as string;
                    //...
                    if (string.IsNullOrEmpty(remoteHash) || disableCatalogUpdateOnStart) //offline
                    {

                    }
                    else //online
                    {
                        if (remoteHash == m_LocalHashValue && !m_Retried) //cache of remote is good and not forcing a retry state
                        {
                            idToLoad = GetTransformedInternalId(location.Dependencies[(int)DependencyHashIndex.Cache]).Replace(".hash", kCatalogExt);//kCatalogExt = .bin or .json
                        }
                        else //remote is different than cache, or no cache
                        {
                            idToLoad = GetTransformedInternalId(location.Dependencies[(int)DependencyHashIndex.Remote]).Replace(".hash", kCatalogExt);
                            m_RemoteHashValue = remoteHash;
                            ...
                        }
                    }
                }

                return idToLoad;
            }
C#

如果在这个自动操作后再用LoadResourceLocationsAsync读取同样的catalog,必然会造成一个key返回两个同样的位置。

标签: 暂无
最后更新:2024-02-01

Ellison

什么都懂点,什么都不精。属于混吃等死,享受生活,过一天算一天的享乐主义。喜欢电影,阅读,以及游戏和美食。

点赞
< 上一篇
下一篇 >

文章评论

razz evil exclaim smile redface biggrin eek confused idea lol mad twisted rolleyes wink cool arrow neutral cry mrgreen drooling persevering
取消回复

Ellison

什么都懂点,什么都不精。属于混吃等死,享受生活,过一天算一天的享乐主义。喜欢电影,阅读,以及游戏和美食。

最新 热点 随机
最新 热点 随机
122. Best Time to Buy and Sell Stock II 16. 3Sum Closest 259. 3Sum Smaller 17. Letter Combinations of a Phone Number Unity中的相机投影矩阵以及推导 15. 3Sum
122. Best Time to Buy and Sell Stock II
259. 3Sum Smaller Fix You 番外 11. Container with most water 【WIP】URP Scriptable Renderer Feature 【Unity小贴士】关于Addressable的热更新 Fix You (五)

COPYRIGHT © 2024 安静如鸡. ALL RIGHTS RESERVED.

Theme Kratos Made By Seaton Jiang