mastertravels77 发表于 2022-3-14 20:46

Unity Addressable 运行时排坑

第一次加载资源时,内存中保存了该资源的一份数据,并初始化该资源的引用数量为1,随后每次加载该资源时,对该引用数量加1.

Release 实际上只是将资源的引用数量减1,也就是LoadAssetsAsync 了多少次,就要Release 多少次。

使用LoadAssetsAsync 加载资源时,同一个key 返回的AsyncOperationHandle 是同一个,但使用AsyncOperationHandle Release LoadAssetsAsync 加载的同一个资源时,仍然需要遵循调用LoadAssetsAsync多少次,就要Release 多少次。

使用InstantiateAsync 加载并实例化资源时,同一个key 返回不同的AsyncOperationHandle<GameObject>。

每一次调用InstantiateAsync 都会增加资源的引用数量,内部应该是先调用了LoadAssetsAsync 相同的流程,然后实例化。

释放InstantiateAsync 加载并实例化的资源时,需要对每个AsyncOperationHandle<GameObject> 进行释放,或释放每个实例化的GameObject。

释放InstantiateAsync 加载并实例化的资源时,使用Release 和ReleaseInstance 的行为是完全相同的,他们都会销毁资源的实例,并且减少资源的引用。

释放LoadAssetsAsync加载的资源时,不会销毁该资源的实例,如果这些实例在其资源被卸载前没有被销毁,他们可能会丢失资源引用,在游戏中表现为材质丢失、模型丢失等。

使用AssetReference.InstantiateAsync加载时,不能使用AssetReference.ReleaseAsset释放,使用AssetReference.ReleaseInstance或者Addressables.Release及Addressables.ReleaseInstance均可,其行为表现一致,均是销毁资源实例,并将该资源的引用减1.

使用AssetReference.LoadAssetsAsync加载时,可以使用AssetReference.ReleaseAsset释放,也可以使用Addressables.Release释放,其行为表现一致,均是将该资源的引用减1.

当调用Addressables.InstantiateAsync 时,将trackHandle 设置为false 时,仅能通过AsyncOperationHandle 来释放资源。

Release AsyncOperationHandle 时,会减少资源的引用数量,当使用该AsyncOperationHandle加载的资源都被释放时,才会invalidates AsyncOperationHandle。这意味着多次调用LoadAssetAsync对同一资源加载若干次,仅当该资源被Release相同次数时,该AsyncOperationHandle才会invalid;而使用InstantiateAsync对同一资源加载并实例化若干次时,每次Release某个实例都仅会令加载并实例化它的AsyncOperationHanleinvalid。

当资源的引用数量减为0时,资源占用的内存并不会立即释放,而是等待资源所在AssetBoundle 被卸载时,才随之释放内存。

当AssetBoundle 中的资源被加载时(资源的引用数量加1),AssetBoundle 的引用数量加1,当AssetBoundle 中的资源被Release 时(资源引用数量减1),AssetBoundle 的引用数量减1,当AssetBoundle 引用数量减为0时,AssetBoundle 被卸载,其占用的内存和其包含的所有被加载的资源所占用的内存都被释放。

当加载AssetBoundle 中的资源时,AssetBoundle 的内部数据会被加载到内存中,这些数据有时候很多,通过平衡包体大小和数量来控制内存占用和内存优化。

当AssetBoundle 中的部分资源依赖另一个AssetBoundle 中的部分资源时,加载前者的任意资源都会使后者(的内部数据和被依赖的资源)作为依赖包而被加载。

当需要加载资源并且实例化多个时,使用LoadAssetsAsync 并保存handle,当需要再次加载并实例化时,使用已经保存的handle 加载,然后使用GameObject.Instantiate 实例化,如此,当资源使用完毕后(如变换场景),只需通过Release handle一次来释放资源。

使用InstantiateAsync 加载并且实例化资源时,如果传入了transform 参数,当场景卸载时,如果该transform 位于场景中,那么对该资源的引用数会自动减1,无需手动调用Release API,但建议还是按照标准流程做。
页: [1]
查看完整版本: Unity Addressable 运行时排坑