记录一下Addressable
参考文章 :addressable介绍
B站有个官方视频 讲解的不错
视频讲解
Addressable的资源更新好像更优化一点,即使一个大包更新也只会更新变化过的内容,把大包拆散。不是整个AB包更新 所以原来很注意的打包力度和划分规则就没太大的必要了是么?好像这样还不确定。他会把所有的多次依赖放一个大包,这个大包还可以拆分下载!
相关概念 名称
1.Address:便于运行时索引的Asset位置标识符。
2.AddressableAssetData目录:存储你工程里所有Addressable Asset的元数据。位置在工程的Assets目录。
3.Asset group:一组可以在构建时处理的Addressable Assets.
4.Asset group schema:定义一组数据,这些数据可以在生成期间分配给Group并使用。
5.AssetReference:类似于直接引用但会延迟初始化的对象。AssetReference对象将GUID存储为可以按需加载的Addressable的GUID。
6.Asynchronous loading:允许在开发过程中更改asset 及其依赖项的位置,而无需修改游戏代码。异步加载是Addressable Asset System的基础实现。
6.Build script:运行asset group处理器来打包assets,并为资源管理器提供地址和资源位置之间的映射。
7.Label:提供用于运行时加载类似项的附加 Addressable Asset标识符。比如(Addressables.DownloadDependenciesAsync("spaceHazards");)。
可以手动标记资源可以寻址,当然正常还是代码来操作
这个方便的是 在编辑器模式下 就可以模拟打包出来的版本,不用真的完整打包。 还能分析依赖,和更新的东西。节省了不少工作
在加载Asset时,
要用到在打包时定义的string 类型地址,两个接口都是异步
UnityEngine.AddressableAssets命名空间下的下列方法:
Addressables.LoadAssetAsync ("AssetAddress");这个加载指定地址的asset。
Addressables.InstantiateAsync("AssetAddress");这个实例化指定地址的asset,并且添加到场景中
加载sub-assets
- Components :目前还不能通过Addressable直接加载GameObject的Components。必须加载或实例化GameObject,然后从其中查找组件引用。要了解如何扩展Addressable以支持组件加载,可以参阅ComponentReference示例。
- Sub-assets:这套系统支持加载Sub-assets,但需要特殊的语法。Sub-assets的例子包括sprite sheet中的sprite ,或者FBX文件中的animation clips等。有关直接加载sprites的示例,可以参考sprite加载示例。
从asset里加载sub-objects可以使用下面的API:
Addressables.LoadAssetAsync <IList >("MySpriteSheetAddress");
如果加载单个的sub-objects,可以使用:
Addressables.LoadAssetAsync ("MySpriteSheetAddress[MySpriteName]");
assets中可用的名称可以在主Addressables group编辑器窗口中查看。此外,还可以使用AssetReference访问assets的子对象。
还可以在界面直接拖 AssetReference 类似原来的Gameobject 不过我觉得不太实用。加载的接口也是两个异步接口:
代码中的 声明方式:public AssetReference 变量
AssetRefMember.LoadAssetAsync ();
或者
AssetRefMember.InstantiateAsync(pos, rot);
说说实际使用的情况
原来的AB规则 在第一次打开Groups窗口时有提示,可以一次性导入。
Addressable Assets开发周期
asset管理
可以给asset绑定一个地址,代码根据这个地址来加载。不用关注它的位置,目录等。直接用地址加载这个很爽。少写很多代码。
Asset Group Schemas
Schemas 定义一组数据,可以在inspector 上把Schemas绑定到一个AssetGroup上。 这个目前不太明白用途
脚本构建
要实现自己的Group规则,需要继续IDataBuilder接口的ScriptableObject assets
Play Mode Scripts
Use Asset Database faster
没啥好说字面意思 Asset DataBase 加载Asset
Simulate Group(advanced)
在不创建AB的情况下 来模拟AB的加载流程,分析布局和依赖,。Asset通过ResourceManager从assetDataBase加载,就假装它们是通过包加载的一样。若要查看游戏期间Bundles加载或卸载的时间,请在Addressables事件查看器窗口(Window>Asset Management>Addressable>Event Viewer)中查看Asset使用情况。Simulate Groups mode可以帮助您模拟加载策略,并调整内容Groups以找到生产和发行版的适当平衡
** Use Existing **
近乎 真正的发布版本,很多团队喜欢使用这种应该。必须通过选择Build>New Build>Default Build Script,或者在游戏脚本中使用AddressableAssetSettings.BuildPlayerContent()方法,在Addressables组窗口(Window>Asset Management>Addressable>group>group)中构建此模式的内容。
内容更新
先本地检查什么内容需要更新 Check命令 ,然后在Update
如果已经修改了任何StaticContent组中的assets,则需要运行“Check for Content Update Restrictions”命令。这将从静态组中得到任何修改后的asset,并将其移动到一个新Groups中。生成新的Asset Groups:
1、打开Unity的Addressables Groups窗口。(Window > Asset Management > Addressables > Groups)
2、Addressables Groups窗口上选择菜单Tools,然后点击Check for Content Update Restrictions。
3、在打开的BuildDataFile对话框中,选择addressables_content_state.bin文件(默认情况下,该文件位于Asset/AddressableAssetsData Project目录中。
此数据用于确定自上次构建应用程序以来有哪些Assets或依赖项已被修改。为了准备更新内容的生成,系统将将这些Assets移动到一个新的Group中。
注意:如果您的所有更改仅限于non-static groups,则此命令将不起任何作用
重要:在开始prepare operation之前,Unity建议你使用版本控制系统打个分支,并在分支上进行操作。prepare operation会以适合的updating content的方式对Asset Groups进行重新排列。分支会确保下次再发布一个新player时,可以快速回滚到你自定义的设定。
构建更新 发布更新
1.还是打开Groups窗口
2.Build->Update a previous Build
3.对话窗口 选择上次打包的构建目录,必现要包含一个contain an addressables_content_state.bin 文件 上一步check时候生成的
构建会生成一个内容目录、一个Hash文件和asset bundles。
生成的内容目录具有与选定应用程序生成中的目录相同的名称,并且会覆盖旧目录和hash文件。应用程序会加载hash文件来确定新目录是否可用。系统从应用程序附带的或已经下载的现有AssetBundles中加载未经修改的Assets。
系统使用addressables_content_state.bin文件中的内容、版本、字符串和位置信息来创建AssetBundles。不包含更新内容的AssetBundles的文件名和原来的一样。如果AssetBundles包含更新的内容,则生成包含更新内容的新AssetBundles,该包会具有新的文件名,以便与原始文件共存。带有新文件名的AssetBundles必须复制到指定的内容托管位置。
系统还可以为静态内容构建AssetBundles,但是并不需要将它们上传到内容托管位置,因为没有Addressableasset entries引用它们。
构建
·用窗口构建, Groups窗口 选Build update a Previous Build
·在Build Data File 对话框打开的时候,选择一个已经存在的APP构建的构建目录,这个目录下必须要包含contain an addressables_content_state.bin 文件。
系统使用addressables_content_state.bin文件中的内容、版本、字符串和位置信息来创建AssetBundles。带有新文件名的AssetBundles必须复制到指定的内容托管位置。(就是固定路径的下载位置)
确定一下 Remote——static 和 Remote_NonStatic 的具体含义和区别
感觉这个更新有点问题,非静态Bundle会下载一些多余数据
注意,上面的示例具有以下意义:
1、任何更改后的本地Assets都会永久残存在在用户的设备上。并且保持未使用状态。
2、如果用户已经缓存了一个非静态Bundle,他们将需要重新下载包,包括未更改的Assets(例如,AssetY和Assetz)。理想情况下,用户没有缓存Bundle,在这种情况下,他们只需要下载新的Remote_non-Static包。
3、如果用户已经缓存了Static_Remote bundle,他们只需要下载更新的Asset(在本例中,通过content_update_group下载AssetL)。但这种情况是很理想的。如果用户没有缓存过Bundle,则必须通过content_update_group下载新的AssetL,并通过未引用的Remote_Static bundle下载现已失效的AssetL。不管初始的缓存状态如何,在完成的某个时候,用户都会在他们的设备上拥有已停用的AssetL,尽管从未被访问或者引用过,但却会被永久的缓存。
Assets 托管服务
这个直接把资源打到服务器,大家更新配置就可以在线使用资源。算是远程工作的利器吧,但一般的项目组应该不敢这么干。而且受网络限制比较多,不如本地稳定,好处是可以资源一直最新,本地存储占用少。速度快点?也是模拟真实环境一个不错的思考。不过感觉没太大必要
真的要用再返回来看吧
Addressable Assets 内存管理
这里加载等返回的变成了句柄,不再强行管理实际asset。直接操作句柄加载释放资源
在所有情况下,释放方法都可以接受加载的Asset,也可以接受Load返回的操作句柄。例如,在场景创建期间(下面描述),Load返回一个AsyncOperationHandle ,您可以通过这个返回的句柄或通过保持句柄同步释放AsyncOperationHandle 。
Asset加载
*原来的引用计数和管理回调都可以交给addressables *
要加载Asset,请使用Addressables.LoadAssetAsync或Addressables.LoadAssetsAsync。
这会将Asset加载到内存中,而不会实例化它。每次加载调用执行时,它都会为每个加载的asset添加一个引用计数。如果您使用相同的地址三次调用LoadAssetAsync,您将得到AsyncOperationHandle结构的三个不同实例,所有这些实例都引用相同的底层操作。对于相应的Asset,该操作的引用计数为3。如果加载成功,则生成的AsyncOperationHandle结构将包含.Result属性中的asset。您可以使用Unity的内置实例化方法使用加载的Asset来实例化,这不会增加Addressable的引用计数。
若要卸载Asset,请使用Addressables.Releases方法,该方法将减少ref计数。当给定Asset的引用计数为零时,该Asset就会被卸载,并减少任何依赖项的引用计数。
Scene 加载
要加载场景,请使用Addressables.LoadSceneAsync。您可以使用此方法以Single模式加载场景,这将关闭所有打开的场景,或以Additive模式加载场景,有关详细信息,请参阅场景模式加载的文档。
若要卸载场景,请使用Addressables.UnloadSceneAsync,或在Single模式下打开新场景。您可以使用Addressables接口或使用SceneManager.LoadScene或SceneManager.LoadSceneAsync方法打开一个新场景。打开一个新场景将关闭当前场景,并适当地减少引用计数。
GameObject 实例化
原来的 实例化可以用,但是没法计数,用他们的最省心,这段比较关键,保证一个合理的内存优化
要加载和实例化GameObject asset,请使用Addressables.InstantiateAsync。这将实例化由指定地址参数定位的Prefab。Addressable系统将加载Prefab及其依赖项,增加所有相关Asset的引用数。
在同一个地址上三次调用InstantiateAsync将导致所有相关Asset的引用数为3。但是,与三次调用LoadAssetAsync不同,每个InstantiateAsync调用都返回指向唯一操作的AsyncOperationHandle。这是因为每个InstantiateAsync的结果都是唯一的实例。InstantiateAsync和其他Load调用之间的另一个区别是可选的trackHandle参数。当设置为false时,必须在释放实例时保留要使用的AsyncOperationHandle。这更有效率,但需要更多的开发精力。
若要销毁实例化的GameObject,请使用Addressables.ReleaseInstance,或关闭包含实例化对象的场景。这个场景可以是加载(从而关闭)在Additive模式或Single模式。这个场景也可以使用Addressable或SceneManagementAPI加载。如上所述,如果将trackHandle设置为false,则只能使用句柄调用Addressables.ReleaseInstance,而不能使用实际的GameObject调用。
注意:如果在未使用Addressables API创建的实例上调用Addressables.ReleaseInstance,或使用trackHandle==false创建的实例,则系统将检测到该实例并返回false,以指示该方法无法释放指定的实例。在这种情况下,实例不会被销毁。
InstantiateAsync有一些相关的开销,因此如果你需要每帧实例化相同的对象数百次,可以考虑通过Addressables API加载,然后通过其他方法实例化。在本例中,可以调用Addressables.LoadAssetAsync,然后保存结果并为该结果调用GameObject.Instantiate()。这允许灵活地以同步方式调用实例化。缺点是Addressable系统不知道你创建了多少实例,如果管理不当,可能会导致内存问题。例如,引用纹理的Prefab将不再具有要引用的有效加载纹理,从而导致BUG出现(或闪退)。这些问题很难跟踪,因为你可能不会立即触发内存GC(请参阅下面关于清除内存的部分)。
Data加载
Data loading不需要它们的AsyncOperationHandle.Result发布的接口,仍然需要释放操作本身。例如Addressables.LoadResourceLocationsAsync和Addressables.GetDownloadSizeAsync。它们加载你可以访问的数据,直到释放操作为止。这个版本可以通过Addressables.Releases完成。
后台交互
在AsyncOperationHandle.Result字段中不返回任何内容的操作具有一个可选参数,可在完成时自动释放操作句柄。如果在这些操作句柄完成后不再需要其中一个操作句柄,请将autoReleaseHandle参数设置为true,以确保清除操作句柄。你希望autoReleaseHandle为false的场景是,你需要在操作句柄完成后检查它的状态。这些接口的例子是Addressables.DownloadDependenciesAsync和Addressables.UnloadScene。
addressable 事件器
这是个好东西,实时看到资源引用和加载计数的情况
使用Addressables Event Viewer窗口监视所有Addressable system 操作的ref计数。要访问编辑器中的窗口,请选择Window>AssetManagement>Addressables>Event Viewer。
·白色垂直行指示发生加载请求的帧。
·蓝色背景表示当前已加载的asset。
·图的绿色部分表示asset的当前参考计数。
AsyncOperationHandle 句柄分析
Addressables API中的几个方法都会返回AsyncOperationHandle结构。此句柄的主要目的是允许访问操作的状态和结果。操作的结果在调用Addressables.Relace或Addressables.ReleaseInstance之前回保持有效。
当操作完成时,AsyncOperationHandle.Status属性要么是AsyncOperationStatus.Succeeded ,要么是AsyncOperationStatus.Failed。如果成功,可以通过AsyncOperationHandle.Result属性访问结果。
你可以定期检查操作状态,也可以使用AsyncOperationHandle.Complete事件注册已完成的回调。当不再需要返回的AsyncOperationHandle结构提供的assets时,应该使用Addressables.Releases方法来释放它。
使用AsyncOperationHandle.Completed回调为完成事件注册侦听器:
imageAsyncOperationHandle实现了IEnumerator,因此可以在coroutines中生成:
imageAddressable还通过AsyncOperationHandle.Task属性支持异步await :
imageAddressables分析器
正常的使用没什么可说的,主要是自定义规则 的需求
AnalyzeRule objects
创建一个AnalyzeRule类的子类,重写以下属性:
CanFix: 告诉分析规则是否被认为是可修正的。
ruleName 分析窗口上用来展示规则的名字。
你还需要重写以下方法,具体如下:
List RefreshAnalysis(AddressableAssetSettings settings)
void FixIssues(AddressableAssetSettings settings)
void ClearAnalysis()注意:如果您的规则被指定为不可修复,则不必重写FixIssues方法。
网友评论