Unity_Addressable_Synchronous Workflow(同步工作流程)
Synchronous Addressables APIs help to more closely mirror Unity asset loading workflows. AsyncOperationHandles
now have a method called WaitForCompletion()
that force the async operation to complete and return the Result
of the operation.
译:
API
Result
The result of WaitForCompletion
is the Result
of the async operation it is called on. If the operation fails, this returns default(TObject)
.
译:
It is possible to get a default(TObject)
for a result when the operation doesn't fail. Async operations that auto release their AsyncOperationHandles
on completion are such cases. Addressables.InitializeAsync()
and any API with a autoReleaseHandle
parameter set to true will return default(TObject)
even though the operations themselves succeeded.
译:
Performance
It is worth noting that calling WaitForCompletion
may have performance implications on your runtime when compared to Resources.Load
or Instantiate
calls directly. If your AssetBundle
is local or has been previously downloaded and cached, these performance hits are likely to be negligible. However, this may not be the case for your individual project setup.
译:
All currently active Asset Load operations are completed when WaitForCompletion
is called on any Asset Load operation, due to how Async operations are handled in the Engine. To avoid unexpected stalls, use WaitForCompletion
when the current operation count is known, and the intention is for all active operations to complete synchronously.
译:
When using WaitForCompletion
, there are performance implications. When using 2021.2.0 or newer, these are minimal. Using an older version can result in delays that scale with the number of Engine Asset load calls that are loading when WaitForCompletion
is called.
译:
It is not recommended that you call WaitForCompletion
on an operation that is going to fetch and download a remote AssetBundle
. Though, it is possible if that fits your specific situation.
译:
Code Sample
Scenes
Due to engine limitations scenes cannot be completed synchronously. Calling WaitForCompletion on an operation returned from Addressables.LoadSceneAsync will not completely load the scene, even if activateOnLoad is set to true. It will wait for dependencies and assets to complete but the scene activation must be done asynchronously. This can be done using the sceneHandle, or by the AsyncOperation from ActivateAsync on the SceneInstance as shown below.
译:由于引擎限制,场景无法同步完成。即使activateOnLoad设置为true,调用Addressables.LoadSceneAsync返回的操作上的WaitForCompletion也无法完全加载场景,它只会等待依赖和资产完成,但场景激活必须异步完成。可以使用sceneHandle或以下示例中SceneInstance上的ActivateAsync的AsyncOperation来完成此操作。
NOTE
Unloading a scene cannot be completed synchronously. Calling WaitForCompleted on a scene unload will not unload the scene or any assets, and a warning will be logged to the console.
译:卸载场景无法同步完成。在场景卸载上调用WaitForCompletion将不会卸载场景或任何资产,并在控制台记录警告。
NOTE
Due to limitations with Scene integration on the main thread through the SceneManager
API, it is possible to lock the Editor or Player when calling WaitForCompletion
in association with scene loading. The issue primarily surfaces when loading two scenes in succession, with the second scene load request having WaitForCompletion
called from its AsyncOperationHandle
.
译:
Since scene loading takes extra frames to fully integrate on the main thread, and WaitForCompletion
locks the main thread, you could hit a situation where Addressables has been informed by the SceneManager
that the first scene is fully loaded, even though it hasn't completed finished all the required operations. At this point, the scene is fully loaded, but the SceneManager
attempts to call UnloadUnusedAssets
, on the main thread, if the scene was loaded in Single
mode. Then, the second scene load request locks the main thread with WaitForCompletion
, but cannot begin loading because SceneManager
requires the UnloadUnusedAssets
to complete before the next scene can begin loading. In order to avoid this deadlock, it is advised that you either load successive scenes asynchronously, or ensure a sufficient delay is added between scene load requests.
译:
由于在主线程上通过SceneManager API进行场景集成的限制,当调用与场景加载相关的WaitForCompletion时,可能会锁定编辑器或播放器。这个问题主要在连续加载两个场景时出现,第二个场景加载请求从其AsyncOperationHandle调用WaitForCompletion。由于场景加载需要额外的帧才能在主线程上完全集成,而WaitForCompletion会锁定主线程,因此您可能会遇到这样一种情况:Addressables已被SceneManager告知第一个场景已完全加载,即使它尚未完成所有所需的操作。此时,场景已完全加载,但是SceneManager尝试在主线程上调用UnloadUnusedAssets,如果场景是在Single模式下加载的,则第二个场景加载请求会使用WaitForCompletion锁定主线程,但无法开始加载,因为SceneManager需要在下一个场景开始加载之前完成UnloadUnusedAssets。为了避免这种死锁情况,建议您要么异步加载连续的场景,要么在场景加载请求之间添加足够的延迟。
Synchronous Addressables with Custom Operations
Addressables supports custom AsyncOperations
which support unique implementations of InvokeWaitForCompletion
. This method can be overridden to implement custom synchronous operations.
译:Addressables支持定制的AsyncOperations,支持InvokeWaitForCompletion的独特实现。可以重写此方法来实现自定义同步操作。
Custom operations work with ChainOperations
and GroupsOperations
. If you require chained operations to be completed synchronously, ensure that your custom operations implement InvokeWaitForCompletion
and create a ChainOperation
using your custom operations. Similarly, GroupOperations
are well suited to ensure a collection of AsyncOperations
, including custom operations, complete together.
译:自定义操作与ChainOperations和GroupsOperations一起使用。如果您需要按顺序完成链接操作,请确保您的自定义操作实现InvokeWaitForCompletion并使用自定义操作创建ChainOperation。
Both ChainOperation
and GroupOperation
have their own implementations of InvokeWaitForCompletion
that relies on the InvokeWaitForCompletion
implementations of the operations they depend on.
译:同样,GroupOperations非常适合确保包括自定义操作在内的一组AsyncOperations一起完成。ChainOperation和GroupOperation都有自己的InvokeWaitForCompletion实现,它们依赖于它们所依赖的操作的InvokeWaitForCompletion实现。
WebGL
WebGL does not support WaitForCompletion
. On WebGL, all files are loaded using a web request. On other platforms, a web request gets started on a background thread and the main thread spins in a tight loop while waiting for the web request to finish. This is how Addressables does it for WaitForCompletion
when a web request is used.
译:WebGL不支持WaitForCompletion。在WebGL上,所有文件都使用Web请求加载。在其他平台上,Web请求在后台线程中启动,而主线程在等待Web请求完成时会旋转一个紧密的循环。当使用Web请求时,Addressables如何处理WaitForCompletion。
Since WebGL is single-threaded, the tight loop blocks the web request and the operation is never allowed to finish. If a web request finishes the same frame it was created, then WaitForCompletion
wouldn't have any issue. However, we cannot guarantee this to be the case, and likely it isn't the case for most instances.
译:由于WebGL是单线程的,紧密的循环会阻塞Web请求,并且操作永远不允许完成。如果Web请求在创建的同一帧中完成,则WaitForCompletion将没有任何问题。但是,我们无法保证这是通常情况,因此这种情况可能不会发生