当前位置: 首页 > news >正文

重庆网站制作服务阳江市网络问政

重庆网站制作服务,阳江市网络问政,云速成美站,正能量网站入口地址【概述】Load Addressable Assets Addressables类提供了加载 Addressable assets 的方法。你可以一次加载一个资源或批量加载资源。为了识别要加载的资源#xff0c;你需要向加载方法传递一个键或键列表。键可以是以下对象之一#xff1a; Address#xff1a;包含你分配给…【概述】Load Addressable Assets Addressables类提供了加载 Addressable assets 的方法。你可以一次加载一个资源或批量加载资源。为了识别要加载的资源你需要向加载方法传递一个键或键列表。键可以是以下对象之一 Address包含你分配给资源的地址的字符串。Label包含分配给一个或多个资源的标签的字符串。AssetReference ObjectAssetReference 的实例。IResourceLocation 实例包含加载资源及其依赖项信息的 intermediate object 。 Addressables 如何加载资源 当你调用其中一个资源加载方法时Addressables 系统开始一个异步操作执行以下任务 查找指定键的资源位置不包括IResourceLocation键。收集依赖项列表。下载任何需要的远程 AssetBundles。将 AssetBundles 加载到内存中。将操作的Result 对象设置为加载的对象。更新操作的Status 并调用任何 Completed 事件侦听器。 如果加载操作成功Status设置为Succeeded可以从Result 对象访问加载的对象或对象。 如果发生错误异常会被复制到操作对象的 [OperationException](https://docs.unity3d.com/Packages/com.unity.addressables2.2/api/UnityEngine.ResourceManagement.AsyncOperations.AsyncOperationHandle.OperationException.html#UnityEngine_ResourceManagement_AsyncOperations_AsyncOperationHandle_OperationException) 成员并且 Status 设置为 Failed。默认情况下异常不会作为操作的一部分抛出。但是你可以为[ResourceManager.ExceptionHandler](https://docs.unity3d.com/Packages/com.unity.addressables2.2/api/UnityEngine.ResourceManagement.ResourceManager.ExceptionHandler.html#UnityEngine_ResourceManagement_ResourceManager_ExceptionHandler)属性分配一个处理函数来处理任何异常。你还可以在 Addressable 系统设置中启用[Log Runtime Exceptions](https://docs.unity3d.com/Packages/com.unity.addressables2.2/manual/AddressableAssetSettings.html)选项将错误记录到 Unity Console 。 当你调用加载多个可寻址资源的方法时可以指定在任何单个加载操作失败时是否中止整个操作或者是否加载操作能加载的任何资源。在这两种情况下操作状态都设置为失败。将 releaseDependenciesOnFailure 参数设置为 true在调用加载方法时在任何失败时中止整个操作。 请参考 Operations 获取有关异步操作和在 Unity 脚本中编写异步代码的更多信息。 将加载的资源与其 key 匹配 Unity 加载单个资源的顺序不一定与传递给加载方法的键列表的顺序相同。 如果需要在组合操作中将资源与用于加载它的键关联可以按照以下步骤执行操作 使用资源键列表加载[IResourceLocation](https://docs.unity3d.com/Packages/com.unity.addressables2.2/api/UnityEngine.ResourceManagement.ResourceLocations.IResourceLocation.html)实例。使用IResourceLocation实例作为键加载单个资源。 IResourceLocation对象包含键信息因此你可以例如保持一个字典来关联 key 和资源。当你调用加载方法如 [LoadAssetsAsync](https://docs.unity3d.com/Packages/com.unity.addressables2.2/api/UnityEngine.AddressableAssets.Addressables.LoadAssetsAsync.html)时操作首先查找与键对应的[IResourceLocation](https://docs.unity3d.com/Packages/com.unity.addressables2.2/api/UnityEngine.ResourceManagement.ResourceLocations.IResourceLocation.html)实例然后使用它加载资源。当你使用 IResourceLocation 加载资源时操作跳过第一步因此分两步执行操作不会增加显著的额外工作。 下面的示例加载一组键的资源并按其地址[PrimaryKey](https://docs.unity3d.com/Packages/com.unity.addressables2.2/api/UnityEngine.ResourceManagement.ResourceLocations.IResourceLocation.PrimaryKey.html#UnityEngine_ResourceManagement_ResourceLocations_IResourceLocation_PrimaryKey)将它们插入到字典中。示例首先加载指定键的资源位置。完成该操作后它为每个位置加载资源并使用Completed事件将单个操作句柄插入到字典中。操作句柄可以用于实例化资源当不再需要资源时可以释放它们。 using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.AddressableAssets; using UnityEngine.Events; using UnityEngine.ResourceManagement.AsyncOperations; using UnityEngine.ResourceManagement.ResourceLocations;internal class LoadWithLocation : MonoBehaviour {public Dictionarystring, AsyncOperationHandleGameObject operationDictionary;public Liststring keys;public UnityEvent Ready;IEnumerator LoadAndAssociateResultWithKey(IListstring keys){if (operationDictionary null)operationDictionary new Dictionarystring, AsyncOperationHandleGameObject();AsyncOperationHandleIListIResourceLocation locations Addressables.LoadResourceLocationsAsync(keys,Addressables.MergeMode.Union, typeof(GameObject));yield return locations;var loadOps new ListAsyncOperationHandle(locations.Result.Count);foreach (IResourceLocation location in locations.Result){AsyncOperationHandleGameObject handle Addressables.LoadAssetAsyncGameObject(location);handle.Completed obj operationDictionary.Add(location.PrimaryKey, obj);loadOps.Add(handle);}yield return Addressables.ResourceManager.CreateGenericGroupOperation(loadOps, true);Ready.Invoke();}void Start(){Ready.AddListener(OnAssetsReady);StartCoroutine(LoadAndAssociateResultWithKey(keys));}private void OnAssetsReady(){float x 0, z 0;foreach (var item in operationDictionary){Debug.Log(${item.Key} {item.Value.Result.name});Instantiate(item.Value.Result,new Vector3(x * 2.0f, 0, z * 2.0f),Quaternion.identity, transform);if (x 9){x 0;z;}}}private void OnDestroy(){foreach (var item in operationDictionary){item.Value.Release();}} }加载方法使用 ResourceManager.CreateGenericGroupOperation 创建一个组操作。这允许方法在所有加载操作完成后继续。在这种情况下该方法调度一个 Ready 事件以通知其他脚本已加载的数据可以使用。 异步加载Asynchronous loading Addressables 系统 API 是异步的并返回一个[AsyncOperationHandle](https://docs.unity3d.com/Packages/com.unity.addressables2.2/api/UnityEngine.ResourceManagement.AsyncOperations.AsyncOperationHandle.html)用于管理操作进度和完成状态。 Addressables 设计为内容位置无关。内容可能需要首先下载或者使用其他可能需要较长时间的方法。要强制同步执行请参考 Synchronous Addressables 了解更多信息。 首次加载资源时handle 至少在一帧后完成。如果内容已经加载不同的异步加载选项的执行时间可能有所不同。你可以如下等待加载完成 Coroutine在继续执行之前始终至少延迟一帧。[Completed](https://docs.unity3d.com/Packages/com.unity.addressables2.2/api/UnityEngine.ResourceManagement.AsyncOperations.AsyncOperationHandle.Completed.html) callback如果内容尚未加载则至少延迟一帧否则回调在同一帧中调用。等待[AsyncOperationHandle.Task](https://docs.unity3d.com/Packages/com.unity.addressables2.2/api/UnityEngine.ResourceManagement.AsyncOperations.AsyncOperationHandle.Task.html#UnityEngine_ResourceManagement_AsyncOperations_AsyncOperationHandle_Task)如果内容尚未加载则至少延迟一帧否则在同一帧中继续执行。 using System.Collections; using UnityEngine; using UnityEngine.AddressableAssets; using UnityEngine.ResourceManagement.AsyncOperations;internal class AsynchronousLoading : MonoBehaviour {private string address tree;private AsyncOperationHandle loadHandle;// 始终至少延迟 1 帧IEnumerator LoadAssetCoroutine(){loadHandle Addressables.LoadAssetAsyncGameObject(address);yield return loadHandle;}// 对于新资产加载至少延迟 1 帧// 已加载资产在当前帧调用回调void LoadAssetCallback(){loadHandle Addressables.LoadAssetAsyncGameObject(address);loadHandle.Completed h {// 此处加载};}// 对于新资产加载至少延迟 1 帧// 已加载资产在当前帧完成 awaitasync void LoadAssetWait(){loadHandle Addressables.LoadAssetAsyncGameObject(address);await loadHandle.Task;}private void OnDestroy(){loadHandle.Release();} }Asynchronous Operation Handles 在 Addressables 中许多任务需要加载或下载信息然后才能返回结果。为了避免阻塞程序执行Addressables 将这些任务实现为异步操作。 与同步操作不同异步操作几乎立即将控制返回给调用方法。然而结果可能需要一段时间才能可用。 当你调用如 LoadAssetAsync 方法时它不会直接返回加载的 asset 。相反它返回一个 AsyncOperationHandle 对象你可以使用它在 asset 可用时访问它们。 你可以使用以下技术来等待异步操作的结果同时允许其他脚本继续处理 Coroutines and [IEnumerator](https://docs.unity3d.com/Packages/com.unity.addressables2.2/manual/AddressableAssetsAsyncOperationHandle.html#coroutine-and-ienumerator-operation-handling) loopsEvent based operation handlingTask based operation handling 你可以阻塞当前线程等待异步操作完成。但这样做可能会引入性能问题和帧率卡顿。有关详细信息请参考 Using operations synchronously 。 释放 AsyncOperationHandle 实例 像 LoadAssetsAsync 这样的方法会返回 AsyncOperationHandle 实例提供操作结果及释放结果和操作对象本身的方法。 只要你想使用结果就必须保留句柄对象。根据情况这可能是一帧直到关卡结束甚至是应用程序的生命周期。使用 [Addressables.Release](https://docs.unity3d.com/Packages/com.unity.addressables2.2/api/UnityEngine.AddressableAssets.Addressables.Release.html) 方法释放操作句柄及任何相关的 Addressable 资源。 释放操作句柄会递减操作加载的任何资产的引用计数并使操作句柄对象本身失效。有关引用计数的更多信息请参考 Memory management 。 如果你在操作的结果范围之外不需要使用它们可以立即释放句柄。一些 Addressables 方法如 [UnloadSceneAsync](https://docs.unity3d.com/Packages/com.unity.addressables2.2/api/UnityEngine.AddressableAssets.Addressables.UnloadSceneAsync.html)允许你在操作完成后自动释放操作句柄。 如果操作失败你仍然应该释放操作句柄。Addressables 会释放失败操作期间加载的任何资产但释放句柄仍然会清除句柄的实例数据。某些加载多个资产的方法如 LoadAssetsAsync允许你选择保留已加载的资产或者在加载操作的任何部分失败时失败并释放所有内容。 Coroutine 和 IEnumerator Operation Handling [AsyncOperationHandle](https://docs.unity3d.com/Packages/com.unity.addressables2.2/api/UnityEngine.ResourceManagement.AsyncOperations.AsyncOperationHandle.html) 实现了 [IEnumerator](https://learn.microsoft.com/dotnet/api/system.collections.ienumerator) 接口并在操作完成前继续迭代。 在协程中你可以 yield 操作句柄等待下一次迭代。当完成时执行流继续到以下语句。你可以将 MonoBehaviour 的 Start 方法实现为协程这是一个让游戏对象加载和实例化它需要的资产的好方法。 以下脚本使用协程在 Start 方法中加载预制件作为其游戏对象的子对象。它在操作完成前 yieldAsyncOperationHandle然后使用相同的句柄实例化预制件。 using System.Collections; using UnityEngine; using UnityEngine.AddressableAssets; using UnityEngine.ResourceManagement.AsyncOperations;internal class LoadWithIEnumerator : MonoBehaviour {public string address;AsyncOperationHandleGameObject opHandle;public IEnumerator Start(){opHandle Addressables.LoadAssetAsyncGameObject(address);// 如果已经完成yield 仍然等待到下一帧所以如果完成就不要 yield。if (!opHandle.IsDone)yield return opHandle;if (opHandle.Status AsyncOperationStatus.Succeeded){Instantiate(opHandle.Result, transform);}else{opHandle.Release();}}void OnDestroy(){opHandle.Release();} }一旦开始你无法取消 Addressables.LoadAssetsAsync。然而在加载完成之前释放句柄会递减句柄的引用计数并在加载完成时自动释放它。 协程中的组操作 要在继续游戏逻辑的下一步之前执行多个操作例如在开始关卡前加载预制件和其他 asset你可以将它们与单个 [Addressables.LoadAssetsAsync](https://docs.unity3d.com/Packages/com.unity.addressables2.2/api/UnityEngine.AddressableAssets.Addressables.LoadAssetsAsync.html)方法调用结合起来如果所有操作都加载 asset。 该方法的 AsyncOperationHandle 与 LoadAssetAsync 相同。你可以在协程中 yield 句柄等待所有操作加载完毕。你也可以传递一个回调方法给 LoadAssetsAsync当操作完成加载特定资产时调用该方法。有关示例请参考 Loading multiple assets 。 你也可以使用[ResourceManager.CreateGenericGroupOperation](https://docs.unity3d.com/Packages/com.unity.addressables2.2/api/UnityEngine.ResourceManagement.ResourceManager.CreateGenericGroupOperation.html)创建一个组操作当其所有成员完成时该操作也完成。 基于事件的操作处理 你可以将委托函数添加到[AsyncOperationHandle](https://docs.unity3d.com/Packages/com.unity.addressables2.2/api/UnityEngine.ResourceManagement.AsyncOperations.AsyncOperationHandle.html)的[Completed](https://docs.unity3d.com/Packages/com.unity.addressables2.2/api/UnityEngine.ResourceManagement.AsyncOperations.AsyncOperationHandle.Completed.html)事件。当操作完成时该操作会调用委托函数。 以下脚本与 coroutine and IEnumerator operation handling 示例执行相同的功能但使用事件委托而不是协程 using UnityEngine; using UnityEngine.AddressableAssets; using UnityEngine.ResourceManagement.AsyncOperations;internal class LoadWithEvent : MonoBehaviour {public string address;AsyncOperationHandleGameObject opHandle;void Start(){// 创建操作opHandle Addressables.LoadAssetAsyncGameObject(address);// 添加事件处理程序opHandle.Completed Operation_Completed;}private void Operation_Completed(AsyncOperationHandleGameObject obj){if (obj.Status AsyncOperationStatus.Succeeded){Instantiate(obj.Result, transform);}else{obj.Release();}}void OnDestroy(){opHandle.Release();} }传递给事件委托的句柄实例与原始方法调用返回的句柄相同。你可以使用任一来访问操作的结果和状态并释放操作句柄和加载的资产。 Task-based operation handling [AsyncOperationHandle](https://docs.unity3d.com/Packages/com.unity.addressables2.2/api/UnityEngine.ResourceManagement.AsyncOperations.AsyncOperationHandle.html) 提供了一个[Task](https://docs.unity3d.com/Packages/com.unity.addressables2.2/api/UnityEngine.ResourceManagement.AsyncOperations.AsyncOperationHandle.Task.html#UnityEngine_ResourceManagement_AsyncOperations_AsyncOperationHandle_Task)对象你可以与 C# 的 async 和 await 关键字一起使用以便顺序调用异步方法并处理结果。 以下示例使用一组 key 加载 Addressable asset 。基于任务的方法与协程或基于事件的方法之间的区别在于调用方法的签名。此方法必须包含 async 关键字并使用 await 关键字与操作句柄的 Task 属性。调用方法在此示例中为 Start在任务完成时暂停操作。然后恢复执行示例在网格模式下实例化所有加载的预制件。 using System.Collections.Generic; using UnityEngine; using UnityEngine.AddressableAssets; using UnityEngine.ResourceManagement.AsyncOperations;internal class LoadWithTask : MonoBehaviour {// 要加载的标签或地址字符串public Liststring keys new Liststring() {characters, animals};// 用于加载和释放资产的操作句柄AsyncOperationHandleIListGameObject loadHandle;public async void Start(){loadHandle Addressables.LoadAssetsAsyncGameObject(keys, // 单个键或键列表addressable {// 为每个加载的资产调用Debug.Log(addressable.name);}, Addressables.MergeMode.Union, // 如何组合多个标签false); // 是否在任何资产加载失败时失败// 等待操作在后台完成await loadHandle.Task;// 实例化结果float x 0, z 0;foreach (var addressable in loadHandle.Result){if (addressable ! null){InstantiateGameObject(addressable,new Vector3(x * 2.0f, 0, z * 2.0f),Quaternion.identity,transform); // 使其成为此对象的子对象if (x 9){x 0;z;}}}}private void OnDestroy(){loadHandle.Release();// 释放与 loadHandle 相关的所有加载资产// 请注意如果你没有使加载的 Addressable 成为此对象的子对象// 那么你需要想出另一种方法在所有单个 Addressable 被销毁时释放句柄。} }使用基于任务的操作处理时你可以使用 C# 的 Task 类方法如 WhenAll来控制你希望并行运行的操作以及希望按顺序运行的操作。以下示例说明了如何等待多个操作完成然后再进行下一任务 // 加载预制件 var prefabOpHandle Addressables.LoadAssetsAsyncGameObject(keys, null, Addressables.MergeMode.Union, false);// 以附加方式加载场景 var sceneOpHandle Addressables.LoadSceneAsync(nextScene,UnityEngine.SceneManagement.LoadSceneMode.Additive);await System.Threading.Tasks.Task.WhenAll(prefabOpHandle.Task, sceneOpHandle.Task);使用同步操作Use operations synchronously 你可以通过调用操作的 WaitForCompletion 方法来等待操作完成而无需使用 yield、等待事件或 async/await。此方法会阻塞当前程序执行线程直到操作完成后再继续当前作用域中的代码执行。 避免在需要大量时间的操作例如需要下载数据的操作上调用 WaitForCompletion因为调用 WaitForCompletion 可能会导致帧率卡顿并中断 UI 响应。 以下示例通过地址加载一个预制件资源等待操作完成然后实例化预制件 using UnityEngine; using UnityEngine.AddressableAssets; using UnityEngine.ResourceManagement.AsyncOperations;internal class LoadSynchronously : MonoBehaviour {public string address;AsyncOperationHandleGameObject opHandle;void Start(){opHandle Addressables.LoadAssetAsyncGameObject(address);opHandle.WaitForCompletion(); // 操作完成时返回if (opHandle.Status AsyncOperationStatus.Succeeded){Instantiate(opHandle.Result, transform);}else{opHandle.Release();}}void OnDestroy(){opHandle.Release();} }自定义操作 要创建自定义操作继承 [AsyncOperationBase](https://docs.unity3d.com/Packages/com.unity.addressables2.2/api/UnityEngine.ResourceManagement.AsyncOperations.AsyncOperationBase-1.html) 类并重写其虚方法。 你可以将派生操作传递给 [ResourceManager.StartOperation](https://docs.unity3d.com/Packages/com.unity.addressables2.2/api/UnityEngine.ResourceManagement.ResourceManager.StartOperation.html) 方法来启动操作并接收 [AsyncOperationHandle](https://docs.unity3d.com/Packages/com.unity.addressables2.2/api/UnityEngine.ResourceManagement.AsyncOperations.AsyncOperationHandle.html) 结构体。[ResourceManager](https://docs.unity3d.com/Packages/com.unity.addressables2.2/api/UnityEngine.ResourceManagement.ResourceManager.html)会注册以这种方式启动的操作。 执行自定义操作 [ResourceManager](https://docs.unity3d.com/Packages/com.unity.addressables2.2/api/UnityEngine.ResourceManagement.ResourceManager.html) 在可选的依赖操作完成后调用自定义操作的 [AsyncOperationBase.Execute](https://docs.unity3d.com/Packages/com.unity.addressables2.2/api/UnityEngine.ResourceManagement.AsyncOperations.AsyncOperationBase-1.Execute.html) 方法。 完成处理 自定义操作完成时调用自定义操作对象的 [AsyncOperationBase.Complete](https://docs.unity3d.com/Packages/com.unity.addressables2.2/api/UnityEngine.ResourceManagement.AsyncOperations.AsyncOperationBase-1.Complete.html)。你可以在 [Execute](https://docs.unity3d.com/Packages/com.unity.addressables2.2/api/UnityEngine.ResourceManagement.AsyncOperations.AsyncOperationBase-1.Execute.html) 方法中调用它也可以在调用外部推迟调用。AsyncOperationBase.Complete 会通知 ResourceManager 操作已完成。ResourceManager会为相关自定义操作实例调用关联的 [AsyncOperationHandle.Completed](https://docs.unity3d.com/Packages/com.unity.addressables2.2/api/UnityEngine.ResourceManagement.AsyncOperations.AsyncOperationHandle.Completed.html) 事件。 终止自定义操作 当操作的[AsyncOperationBase.ReferenceCount](https://docs.unity3d.com/Packages/com.unity.addressables2.2/api/UnityEngine.ResourceManagement.AsyncOperations.AsyncOperationBase-1.DecrementReferenceCount.html)归零时ResourceManager 会调用自定义操作的 [AsyncOperationBase.Destroy](https://docs.unity3d.com/Packages/com.unity.addressables2.2/api/UnityEngine.ResourceManagement.AsyncOperations.AsyncOperationBase-1.Destroy.html) 方法。释放引用 [AsyncOperationHandle](https://docs.unity3d.com/Packages/com.unity.addressables2.2/api/UnityEngine.ResourceManagement.AsyncOperations.AsyncOperationHandle.html) 时AsyncOperationBase.ReferenceCount会减少使用 [Addressables.Release](https://docs.unity3d.com/Packages/com.unity.addressables2.2/api/UnityEngine.AddressableAssets.Addressables.Release.html) 或当自定义操作内部调用 [AsyncOperationBase.DecrementReferenceCount](https://docs.unity3d.com/Packages/com.unity.addressables2.2/api/UnityEngine.ResourceManagement.AsyncOperations.AsyncOperationBase-1.DecrementReferenceCount.html)时。AsyncOperationBase.Destroy 是你应释放任何与自定义操作相关的内存或资源的地方。 类型和无类型 Operation Handles 大多数启动操作的Addressables方法返回一个泛型[AsyncOperationHandleT](https://docs.unity3d.com/Packages/com.unity.addressables2.2/api/UnityEngine.ResourceManagement.AsyncOperations.AsyncOperationHandle-1.html)结构体允许操作 [AsyncOperationHandle.Completed](https://docs.unity3d.com/Packages/com.unity.addressables2.2/api/UnityEngine.ResourceManagement.AsyncOperations.AsyncOperationHandle.Completed.html)事件和[AsyncOperationHandle.Result](https://docs.unity3d.com/Packages/com.unity.addressables2.2/api/UnityEngine.ResourceManagement.AsyncOperations.AsyncOperationHandle.Result.html#UnityEngine_ResourceManagement_AsyncOperations_AsyncOperationHandle_Result)对象的类型安全。你也可以使用非泛型 [AsyncOperationHandle](https://docs.unity3d.com/Packages/com.unity.addressables2.2/api/UnityEngine.ResourceManagement.AsyncOperations.AsyncOperationHandle.html) 结构并根据需要在两种句柄类型之间进行转换。 如果尝试将非泛型句柄转换为错误类型的泛型句柄会发生运行时异常。例如 // 使用类型句柄加载资源 AsyncOperationHandleTexture2D textureHandle Addressables.LoadAssetAsyncTexture2D(mytexture);// 将 AsyncOperationHandleTexture2D 转换为 AsyncOperationHandle AsyncOperationHandle nonGenericHandle textureHandle;// 将 AsyncOperationHandle 转换为 AsyncOperationHandleTexture2D AsyncOperationHandleTexture2D textureHandle2 nonGenericHandle.ConvertTexture2D();// 这会抛出异常因为需要 Texture2D AsyncOperationHandleTexture textureHandle3 nonGenericHandle.ConvertTexture();报告操作进度 AsyncOperationHandle提供以下方法用于监控和报告操作的进度 [GetDownloadStatus](https://docs.unity3d.com/Packages/com.unity.addressables2.2/api/UnityEngine.ResourceManagement.AsyncOperations.AsyncOperationHandle.GetDownloadStatus.html): 返回一个[DownloadStatus](https://docs.unity3d.com/Packages/com.unity.addressables2.2/api/UnityEngine.ResourceManagement.AsyncOperations.DownloadStatus.html)结构。该结构包含有关已下载字节数和仍需下载的字节数的信息。[DownloadStatus.Percent](https://docs.unity3d.com/Packages/com.unity.addressables2.2/api/UnityEngine.ResourceManagement.AsyncOperations.DownloadStatus.Percent.html#UnityEngine_ResourceManagement_AsyncOperations_DownloadStatus_Percent) 报告已下载字节的百分比。[AsyncOperationHandle.PercentComplete](https://docs.unity3d.com/Packages/com.unity.addressables2.2/api/UnityEngine.ResourceManagement.AsyncOperations.AsyncOperationHandle.PercentComplete.html#UnityEngine_ResourceManagement_AsyncOperations_AsyncOperationHandle_PercentComplete): 返回所有子操作完成的平均百分比。例如如果一个操作有五个子操作每个子操作代表总数的 20%。该值不考虑各个子操作需要下载的数据量。 例如如果你调用 [Addressables.DownloadDependenciesAsync](https://docs.unity3d.com/Packages/com.unity.addressables2.2/api/UnityEngine.AddressableAssets.Addressables.DownloadDependenciesAsync.html) 并且需要下载五个 AssetBundlesGetDownloadStatus 会告诉你所有子操作总字节数的百分比。PercentComplete 告诉你完成的操作数量的百分比而不考虑它们的大小。 如果你调用[LoadAssetAsync](https://docs.unity3d.com/Packages/com.unity.addressables2.2/api/UnityEngine.AddressableAssets.Addressables.LoadAssetAsync.html)并且在加载资产之前需要下载一个 bundle下载百分比可能会产生误导。因为在操作完成之前 GetDownloadStatus 的值已达到 100%而此时操作还有其他子操作要进行。当下载子操作完成时 PercentComplete 的值为 50%当实际加载到内存中完成时值为 100%。 同步加载Synchronous loading 同步 Addressables API 帮助镜像 Unity 资源加载工作流。AsyncOperationHandles有一个名为 WaitForCompletion()的方法可以强制 asynchronous operation 完成并返回操作的result。 WaitForCompletion的result是它调用的异步操作的结果。如果操作失败则返回default(TObject)。 当操作没有失败时你也可能获得 default(TObject) 结果。这种情况适用于自动在完成时释放其 AsyncOperationHandle 实例的异步操作。Addressables.InitializeAsync和任何带有 autoReleaseHandle 参数设置为 true 的 API 都会返回 default(TObject)即使操作成功。 性能考虑 与直接调用 Resources.Load 或 Instantiate 相比调用 WaitForCompletion 可能会对运行时性能产生影响。如果 AssetBundle 是本地的或已经下载并缓存这些性能影响很小。 当 WaitForCompletion 在任何资源加载操作上调用时所有活跃的资源加载操作都将完成这是因为 Unity 处理异步操作的方式。为了避免意外的停顿请在已知当前操作数量时使用WaitForCompletion并希望所有活动操作同步完成。 不要在将要获取和下载远程 AssetBundle 的操作上调用 WaitForCompletion。 同步加载示例 void Start() {// 强制同步加载 GameObject 的基本用例var op Addressables.LoadAssetAsyncGameObject(myGameObjectKey);GameObject go op.WaitForCompletion();// 执行其他工作...Addressables.Release(op); }场景限制导致的死锁 Unity 无法同步完成场景加载。即使 activateOnLoad 设置为 true调用[Addressables.LoadSceneAsync](https://docs.unity3d.com/Packages/com.unity.addressables2.2/api/UnityEngine.AddressableAssets.Addressables.LoadSceneAsync.html)返回的操作上的WaitForCompletion也不能完全加载场景。它会等待依赖项和资源完成但场景激活必须异步完成。 这可以通过 sceneHandle 或 SceneInstance 上的 ActivateAsync 的 [AsyncOperation](https://docs.unity3d.com/2023.1/Documentation/ScriptReference/AsyncOperation.html) 来完成 IEnumerator LoadScene(string myScene) {var sceneHandle Addressables.LoadSceneAsync(myScene, LoadSceneMode.Additive);SceneInstance sceneInstance sceneHandle.WaitForCompletion();yield return sceneInstance.ActivateAsync();// 执行其他工作... 现在场景已完成并集成 }Unity 不能同步卸载场景。调用WaitForCompletion来卸载场景不会卸载场景或任何资源并会在控制台中记录警告。 由于 SceneManager API 在主线程上的场景集成限制当调用 WaitForCompletion 加载场景时可能会锁定 Unity 编辑器或 Player 。这种问题发生在连续加载两个场景时第二个场景加载请求从其 AsyncOperationHandle 调用了WaitForCompletion。 场景加载需要额外的帧才能在主线程上完全集成而**WaitForCompletion**锁定主线程因此可能会出现 Addressables 被 SceneManager 通知第一个场景已完全加载但实际上尚未完成所有操作的情况。在此时场景已完全加载但 SceneManager 尝试在主线程上调用 UnloadUnusedAssets如果场景以单模式加载。然后第二个场景加载请求通过 WaitForCompletion 锁定主线程但由于 SceneManager 需要完成 UnloadUnusedAssets无法开始加载下一个场景。 为避免此死锁要么异步加载连续的场景要么在场景加载请求之间添加延迟。 另一个问题是在Awake中异步操作未完全加载场景时调用WaitForCompletion。这可能会阻塞主线程阻止其他正在进行的异步操作如卸载 bundle完成。为避免此死锁在 Start 中调用 WaitForCompletion。 请注意Addressables 在 SceneManager.sceneUnloaded 中注册了一个回调卸载任何卸载的 Addressable 场景。如果没有其他场景从 bundle 中加载这可能触发场景 bundle 卸载。 自定义操作 Addressables 支持自定义 AsyncOperation 实例它们支持 InvokeWaitForCompletion 的唯一实现。可以重写此方法以实现自定义的同步操作。 自定义操作适用于 ChainOperation 和 GroupsOperation 实例。如果希望同步完成链操作请使自定义操作实现 InvokeWaitForCompletion 并使用自定义操作创建 ChainOperation。同样GroupOperations 非常适合使一组 AsyncOperations包括自定义操作一起完成。 ChainOperation 和 GroupOperation 都有自己的 InvokeWaitForCompletion 实现依赖于它们所依赖的操作的 InvokeWaitForCompletion 实现。 WebGL 支持 WebGL 不支持 WaitForCompletion。在 WebGL 上网络请求加载所有文件。在其他平台上网络请求在后台线程启动主线程在等待网络请求完成时处于紧密循环tight loop状态。Addressables 使用这种方式处理网络请求时的 WaitForCompletion。 由于 WebGL 是单线程的紧密循环会阻塞网络请求操作永远无法完成。如果网络请求在创建的同一帧完成则 WaitForCompletion 不会有任何问题。然而这并不保证。 Load Assets 你可以使用 LoadAssetAsync 或 LoadAssetsAsync 方法在运行时加载一个或多个资源。 加载单个资源 使用 [LoadAssetAsync](https://docs.unity3d.com/Packages/com.unity.addressables2.2/api/UnityEngine.AddressableAssets.Addressables.LoadAssetsAsync.html) 方法加载单个 Addressable 资源通常以地址作为键 using System.Collections; using UnityEngine; using UnityEngine.AddressableAssets; using UnityEngine.ResourceManagement.AsyncOperations;internal class LoadAddress : MonoBehaviour {public string key;AsyncOperationHandleGameObject opHandle;public IEnumerator Start(){opHandle Addressables.LoadAssetAsyncGameObject(key);yield return opHandle;if (opHandle.Status AsyncOperationStatus.Succeeded){GameObject obj opHandle.Result;Instantiate(obj, transform);}}void OnDestroy(){opHandle.Release();} }你可以在调用 LoadAssetAsync 时使用 label 或其他类型的键而不仅仅是地址。然而如果键解析出多个资源则只会加载找到的第一个资源。例如如果你使用一个 label 调用此方法该 label 应用于多个资源则 Addressables 返回首先找到的那些资源之一。 加载多个资源 使用[LoadAssetsAsync](https://docs.unity3d.com/Packages/com.unity.addressables2.2/api/UnityEngine.AddressableAssets.Addressables.LoadAssetsAsync.html)方法在一次操作中加载多个 Addressable 资源。使用此方法时可以指定一个键如 label 或一组键。 指定多个键时可以指定合并模式来设置匹配每个键的资源如何组合 Union: 包含匹配任何键的资源Intersection: 包含匹配每个键的资源UseFirst: 仅包含第一个解析为有效位置的键的资源 using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.AddressableAssets; using UnityEngine.ResourceManagement.AsyncOperations;internal class LoadMultiple : MonoBehaviour {// 要加载的标签字符串public Liststring keys new Liststring() {characters, animals};// 用于加载和释放资源的操作句柄AsyncOperationHandleIListGameObject loadHandle;// 通过标签加载 Addressablespublic IEnumerator Start(){float x 0, z 0;loadHandle Addressables.LoadAssetsAsyncGameObject(keys,addressable {// 每加载一个资源都会调用InstantiateGameObject(addressable,new Vector3(x * 2.0f, 0, z * 2.0f),Quaternion.identity,transform);if (x 9){x 0;z;}}, Addressables.MergeMode.Union, // 如何组合多个标签 false); // 如果任何资源加载失败是否释放yield return loadHandle;}private void OnDestroy(){loadHandle.Release();// 释放与 loadHandle 关联的所有加载资源// 注意如果你没有将加载的 Addressables 设为此对象的子对象// 那么你需要设计另一种方法来在所有单独的 Addressables 被销毁时释放句柄。} }要指定如何处理加载错误请使用releaseDependenciesOnFailure参数。如果为true则在加载任何单个资源时遇到错误时操作失败。操作和已加载的任何资源都会被释放。 如果为 false则操作会尽可能加载所有对象并且不会释放操作。如果操作失败操作仍然会以 Failed 状态完成。此外返回的资源列表中会在失败资源本应出现的位置包含 null 值。 当加载必须作为一个集合使用的一组资源时将 releaseDependenciesOnFailure 设置为 true。例如如果你加载游戏关卡的资源你可能会让整个操作失败而不是只加载部分所需资源。 根据位置加载资源Load assets by location 当你通过地址、标签或AssetReference加载 Addressable 资源时Addressables 系统首先会查找资源的位置并使用[IResourceLocation](https://docs.unity3d.com/Packages/com.unity.addressables2.2/api/UnityEngine.ResourceManagement.ResourceLocations.IResourceLocation.html)实例下载所需的 AssetBundles 及其任何依赖项。要执行资源加载操作先使用 [LoadResourceLocationsAsync](https://docs.unity3d.com/Packages/com.unity.addressables2.2/api/UnityEngine.AddressableAssets.Addressables.LoadResourceLocationsAsync.html) 获取 IResourceLocation 对象然后使用这些对象作为键来加载或实例化资源。 IResourceLocation对象包含加载一个或多个资源所需的信息。 LoadResourceLocationsAsync 方法永远不会失败。如果无法将指定的键解析到任何资源的位置它会返回一个空列表。你可以通过在 type 参数中指定特定类型来限制返回的资源位置的类型。 以下示例加载带有 knight 或 villager 标签的所有资源的位置 AsyncOperationHandleIListIResourceLocation handle Addressables.LoadResourceLocationsAsync(new string[] {knight, villager},Addressables.MergeMode.Union);yield return handle;// ...handle.Release();加载子对象sub-objects的 Location Unity 在运行时生成SubObjects的位置以减小内容目录的大小并提高运行时性能。当你使用带有子对象的资源的键调用[LoadResourceLocationsAsync](https://docs.unity3d.com/Packages/com.unity.addressables2.2/api/UnityEngine.AddressableAssets.Addressables.LoadResourceLocationsAsync.html)且不指定类型时该方法会为所有子对象和主对象生成 IResourceLocation 实例。同样如果你不指定用于指向带有子对象的资源的AssetReference的子对象那么系统会为每个子对象生成 IResourceLocation 实例。 例如如果你加载一个 FBX 资源的位置地址为 myFBXObject你可能会获得三个资源的位置一个 GameObject、一个网格和一个材质。如果你在地址中指定类型 myFBXObject[Mesh]则只会得到网格对象。你也可以使用 LoadResourceLocationsAsync 方法的 type 参数来指定类型。 加载场景Load a Scene 使用 [Addressables.LoadSceneAsync](https://docs.unity3d.com/Packages/com.unity.addressables2.2/api/UnityEngine.AddressableAssets.Addressables.LoadSceneAsync.html) 方法通过地址或其他 Addressable key object 加载 Addressable 场景资源。 Addressables.LoadSceneAsync 内部使用了 Unity 引擎的[SceneManager.LoadSceneAsync](https://docs.unity3d.com/2023.1/Documentation/ScriptReference/SceneManagement.SceneManager.LoadSceneAsync.html)方法。影响 SceneManager.LoadSceneAsync 行为的 API 也会以相同的方式影响 Addressables.LoadSceneAsync例如[Application.backgroundLoadingPriority](https://docs.unity3d.com/2023.1/Documentation/ScriptReference/Application-backgroundLoadingPriority.html)。 Addressables.LoadSceneAsync方法的剩余参数对应于 SceneManager.LoadSceneAsync 方法的参数 loadMode是将加载的场景添加到当前场景中还是卸载并替换当前场景。loadSceneParameters包括 loadMode 和 localPhysicsMode。用于在加载场景时指定创建 2D 还是 3D physics scene 。activateOnLoad是否在场景加载完成后立即激活场景还是等到调用 SceneInstance 对象的 [ActivateAsync](https://docs.unity3d.com/Packages/com.unity.addressables2.2/api/UnityEngine.ResourceManagement.ResourceProviders.SceneInstance.ActivateAsync.html)方法后再激活。对应于[AsyncOperation.allowSceneActivation](https://docs.unity3d.com/2023.1/Documentation/ScriptReference/AsyncOperation-allowSceneActivation.html)选项。默认值为 true。priority用于加载场景的 AsyncOperation 的优先级。对应于[AsyncOperation.priority](https://docs.unity3d.com/2023.1/Documentation/ScriptReference/AsyncOperation-priority.html)选项。默认值为 100。 以下示例以附加模式additively加载场景。加载场景的组件存储操作句柄并在 parent GameObject 被销毁时使用它来卸载和释放场景 using UnityEngine; using UnityEngine.AddressableAssets; using UnityEngine.ResourceManagement.AsyncOperations; using UnityEngine.ResourceManagement.ResourceProviders; using UnityEngine.SceneManagement;internal class LoadSceneByAddress : MonoBehaviour {public string key; // address stringprivate AsyncOperationHandleSceneInstance loadHandle;void Start(){loadHandle Addressables.LoadSceneAsync(key, LoadSceneMode.Additive);}void OnDestroy(){Addressables.UnloadSceneAsync(loadHandle);} }有关更多示例请参阅 Addressables 示例库中的 Scene loading project 。 如果你使用 [LoadSceneMode.Single](https://docs.unity3d.com/2023.1/Documentation/ScriptReference/SceneManagement.LoadSceneMode.Single.html) 加载场景Unity 运行时会卸载当前场景并调用 [Resources.UnloadUnusedAssets](https://docs.unity3d.com/2023.1/Documentation/ScriptReference/Resources.UnloadUnusedAssets.html)。有关更多信息请参阅 Releasing Addressable assets 。 在编辑器中即使场景被打包在不可用的远程包中并且你将 Play 模式脚本设置为使用现有构建你也可以始终加载当前项目中的场景。编辑器使用资源数据库加载场景。 在场景中使用 Addressables 如果场景是 Addressable你可以像使用其他资源一样使用场景中的 Addressable 资源。你可以在场景中放置预制件和其他资源并将资源分配给组件属性。如果你使用了非 Addressable 资源则该资源会成为场景的隐式依赖项implicit dependency并且在构建内容时构建系统会将其打包到与场景相同的 AssetBundle 中。Addressable 资源根据它们所在的组打包到各自的 AssetBundle 中。 如果场景不是 Addressable 那么你直接添加到场景层次结构中的任何 Addressable 资源都会成为隐式依赖项Unity 会将这些资源的副本包含在内置场景数据built-in scene data中即使它们也存在于 Addressable 组中。对于任何资源例如分配给场景中 GameObject 上的组件的材质也是如此。 在自定义组件类中你可以使用 [AssetReference](https://docs.unity3d.com/Packages/com.unity.addressables2.2/api/UnityEngine.AddressableAssets.AssetReference.html) 字段来允许在非 Addressable 场景中分配 Addressable 资源。否则你可以使用地址和 label 在运行时从脚本中加载资源。无论场景是否为 Addressable都必须在代码中加载 AssetReference。 加载 AssetBundles 你可以通过 BundledAssetGroupSchema 类控制 AssetBundles 的加载方式。可以通过脚本 API 或者在AddressablesAssetGroup inspector 的高级选项中设置这些选项。 使用 UnityWebRequest 加载本地包 Addressables 可以通过两种引擎 API 加载 AssetBundlesUnityWebRequest.GetAssetBundle 和 AssetBundle.LoadFromFileAsync。默认行为是在 AssetBundle 位于本地存储时使用 AssetBundle.LoadFromFileAsync在 AssetBundle 路径是 URL 时使用 UnityWebRequest。 你可以通过将 BundledAssetGroupSchema.UseUnityWebRequestForLocalBundles 设置为 true 来覆盖此行为。也可以通过 BundledAssetGroupSchema GUI 设置。 以下是几种适用情况 你正在发布使用 LZMA 压缩的本地 AssetBundles因为你希望发布的游戏包尽可能小。在这种情况下你可能希望使用 UnityWebRequest 将这些 AssetBundles 重新压缩为本地磁盘缓存中的 LZ4。你正在发布 Android 游戏并且你的 APK 包含使用默认 APK 压缩的 AssetBundles。你希望将整个本地 AssetBundle 加载到内存中以避免磁盘查找。如果你使用 UnityWebRequest 并禁用缓存整个 AssetBundle 文件将被加载到内存缓存中。这会增加你的运行时内存使用但可能会提高加载性能因为它消除了初始 AssetBundle 加载后的磁盘查找。 上述前两种情况会导致 AssetBundle 在玩家设备上存在两次原始表示和缓存表示。这意味着初始加载解压缩和复制到缓存比后续加载从缓存加载更慢。 处理下载错误Handle download errors 当下载失败时RemoteProviderException 包含可用于确定如何处理失败的错误。RemoteProviderException 可能是 AsyncOperationHandle.OperationException 或内部异常。如下所示 using UnityEngine; using UnityEngine.AddressableAssets; using UnityEngine.ResourceManagement.AsyncOperations; using UnityEngine.ResourceManagement.Exceptions;internal class HandleDownloadError : MonoBehaviour {private AsyncOperationHandle m_Handle;void LoadAsset(){m_Handle Addressables.LoadAssetAsyncGameObject(addressKey);m_Handle.Completed handle {string dlError GetDownloadError(m_Handle);if (!string.IsNullOrEmpty(dlError)){// 处理错误}};}string GetDownloadError(AsyncOperationHandle fromHandle){if (fromHandle.Status ! AsyncOperationStatus.Failed)return null;RemoteProviderException remoteException;System.Exception e fromHandle.OperationException;while (e ! null){remoteException e as RemoteProviderException;if (remoteException ! null)return remoteException.WebRequestResult.Error;e e.InnerException;}return null;} }可能的错误字符串包括 “Request aborted”请求已中止“Unable to write data”无法写入数据“Malformed URL”URL 格式错误“Out of memory”内存不足“No Internet Connection”没有网络连接“Encountered invalid redirect (missing Location header?)”遇到无效重定向缺少位置头“Cannot modify request at this time”此时无法修改请求“Unsupported Protocol”不支持的协议“Destination host has an erroneous SSL certificate”目标主机有错误的 SSL 证书“Unable to load SSL Cipher for verification”无法加载 SSL 密码进行验证“SSL CA certificate error”SSL CA 证书错误“Unrecognized content-encoding”无法识别的内容编码“Request already transmitted”请求已发送“Invalid HTTP Method”无效的 HTTP 方法“Header name contains invalid characters”头名称包含无效字符“Header value contains invalid characters”头值包含无效字符“Cannot override system-specified headers”无法覆盖系统指定的头“Backend Initialization Error”后台初始化错误“Cannot resolve proxy”无法解析代理“Cannot resolve destination host”无法解析目标主机“Cannot connect to destination host”无法连接到目标主机“Access denied”访问被拒绝“Generic/unknown HTTP error”通用/未知 HTTP 错误“Unable to read data”无法读取数据“Request timeout”请求超时“Error during HTTP POST transmission”HTTP POST 传输过程中出错“Unable to complete SSL connection”无法完成 SSL 连接“Redirect limit exceeded”重定向限制超出“Received no data in response”未收到响应数据“Destination host does not support SSL”目标主机不支持 SSL“Failed to transmit data”传输数据失败“Failed to receive data”接收数据失败“Login failed”登录失败“SSL shutdown failed”SSL 关闭失败“Redirect limit is invalid”重定向限制无效“Not implemented”未实现“Data Processing Error, see Download Handler error”数据处理错误请参见下载处理程序错误“Unknown Error”未知错误 卸载 Addressable 资源 Addressables 系统使用引用计数来检查资源是否在使用中。这意味着你必须在完成使用后释放每个加载或实例化的资源。有关更多信息请参考 Memory Management 。 当你卸载一个场景时它所属的 AssetBundle 也会被卸载。这会卸载与该场景相关的资源包括从原始场景移动到不同场景的任何 GameObjects。 当 Unity 使用 [LoadSceneMode.Single](https://docs.unity3d.com/2023.1/Documentation/ScriptReference/SceneManagement.LoadSceneMode.Single.html) 模式加载场景时会自动调用 UnloadUnusedAssets。为了防止场景及其资源被卸载可以在希望手动卸载场景之前保留对场景加载操作句柄的引用。为此可以对加载操作句柄使用 [ResourceManager.Acquire](https://docs.unity3d.com/Packages/com.unity.addressables2.2/api/UnityEngine.ResourceManagement.ResourceManager.Acquire.html#UnityEngine_ResourceManagement_ResourceManager_Acquire_UnityEngine_ResourceManagement_AsyncOperations_AsyncOperationHandle_)。 单独从场景加载的各个 Addressables 及其操作句柄不会被释放。你必须调用 [Addressables.Release](https://docs.unity3d.com/Packages/com.unity.addressables2.2/api/UnityEngine.AddressableAssets.Addressables.Release.html) 来释放这些资源。例外情况是当你使用 [Addressables.InstantiateAsync](https://docs.unity3d.com/Packages/com.unity.addressables2.2/api/UnityEngine.AddressableAssets.Addressables.InstantiateAsync.html) 并设置 trackHandle 为 true默认值实例化的任何 Addressable 资源会自动释放。 更改资源 URL 你可以通过以下几种方式在运行时修改 Addressables 用于加载资源的 URL Static Profile Variables 当你定义 RemoteLoadPath Profile variable 变量时可以使用静态属性来指定应用加载远程内容包括目录、目录哈希文件和 AssetBundles的 URL 的全部或部分。有关在 Profile 变量中指定属性名称的信息请参考 Profile variable syntax 。 静态属性的值必须在 Addressables 初始化之前设置。初始化后更改值无效。 ID Transform Method 你可以为 [Addressables.ResourceManager](https://docs.unity3d.com/Packages/com.unity.addressables2.2/api/UnityEngine.AddressableAssets.Addressables.ResourceManager.html#UnityEngine_AddressableAssets_Addressables_ResourceManager) 对象的 [InternalIdTransformFunc](https://docs.unity3d.com/Packages/com.unity.addressables2.2/api/UnityEngine.ResourceManagement.ResourceLocations.IResourceLocation.InternalId.html#UnityEngine_ResourceManagement_ResourceLocations_IResourceLocation_InternalId) 属性分配一个方法以单独更改 Addressables 加载资源的 URL。必须在相关操作开始之前分配该方法否则将使用默认 URL。 使用 TransformInternalId 对于远程托管很有用。给定单个 IResourceLocation你可以将 ID 转换为运行时指定的服务器。这对于服务器 IP 地址更改或使用不同 URL 提供不同应用资源变体非常有用。 ResourceManager在查找资源时调用TransformInternalId方法将资源的[IResourceLocation](https://docs.unity3d.com/Packages/com.unity.addressables2.2/api/UnityEngine.ResourceManagement.ResourceLocations.IResourceLocation.html)实例传递给你的方法。你可以更改IResourceLocation的[InternalId](https://docs.unity3d.com/Packages/com.unity.addressables2.2/api/UnityEngine.ResourceManagement.ResourceLocations.IResourceLocation.InternalId.html#UnityEngine_ResourceManagement_ResourceLocations_IResourceLocation_InternalId)属性并将修改后的对象返回给 ResourceManager。 以下示例演示了如何为所有 AssetBundles 的 URL 追加查询字符串 using UnityEngine.ResourceManagement.ResourceLocations; using UnityEngine.ResourceManagement.ResourceProviders; using UnityEngine.AddressableAssets;static class IDTransformer {// 实现一个方法来转换 location 的内部 idstatic string MyCustomTransform(IResourceLocation location){if (location.ResourceType typeof(IAssetBundleResource) location.InternalId.StartsWith(http, System.StringComparison.Ordinal))return location.InternalId ?customQueryTagcustomQueryValue;return location.InternalId;}// 用你的自定义方法覆盖 Addressables 转换方法。// 这可以设置为 null 以恢复默认行为。[RuntimeInitializeOnLoadMethod]static void SetInternalIdTransform(){Addressables.InternalIdTransformFunc MyCustomTransform;} }WebRequest Override 你可以为 Addressable 对象的 WebRequestOverride 属性分配一个方法以单独更改用于下载文件如 AssetBundle 或目录.json文件的 UnityWebRequest。必须在相关操作开始之前分配该方法否则将使用默认的 UnityWebRequest。 ResourceManager 在调用 UnityWebRequest.SendWebRequest 之前调用 WebRequestOverride并将下载的 UnityWebRequest 传递给你的方法。 以下示例显示了如何为所有 AssetBundles 和目录的 URL 追加查询字符串 using UnityEngine; using UnityEngine.Networking; using UnityEngine.AddressableAssets;internal class WebRequestOverride : MonoBehaviour {// 注册以覆盖 Addressables 创建的用于下载的 WebRequestsprivate void Start(){Addressables.WebRequestOverride EditWebRequestURL;}// 覆盖 WebRequest 的 url传递给该方法的请求是 Addressables 标准使用的请求。private void EditWebRequestURL(UnityWebRequest request){if (request.url.EndsWith(.bundle, StringComparison.OrdinalIgnoreCase))request.url request.url ?customQueryTagcustomQueryValue;else if (request.url.EndsWith(.json, StringComparison.OrdinalIgnoreCase) || request.url.EndsWith(.hash, StringComparison.OrdinalIgnoreCase))request.url request.url ?customQueryTagcustomQueryValue;} }预加载依赖项Preload dependencies 当你远程分发内容时可以通过在应用需要它们之前预先下载依赖项来提高性能。例如你可以在游戏首次启动时下载必要的内容以确保用户在游戏过程中不会等待内容加载。 下载依赖项 使用 [Addressables.DownloadDependenciesAsync](https://docs.unity3d.com/Packages/com.unity.addressables2.2/api/UnityEngine.AddressableAssets.Addressables.DownloadDependenciesAsync.html) 方法确保加载某个 Addressable key 所需的所有依赖项都已安装在应用的本地内容或下载缓存中 string key assetKey;// 检查下载大小 AsyncOperationHandlelong getDownloadSize Addressables.GetDownloadSizeAsync(key); yield return getDownloadSize;// 如果下载大小大于 0则下载所有依赖项。 if (getDownloadSize.Result 0) {AsyncOperationHandle downloadDependencies Addressables.DownloadDependenciesAsync(key);yield return downloadDependencies;if(downloadDependencies.Status AsyncOperationStatus.Failed)Debug.LogError(Failed to download dependencies for key);// 我们需要释放下载句柄以便可以加载资源downloadDependencies.Release(); }获取进度更新Get progress updates [AsyncOperationHandle](https://docs.unity3d.com/Packages/com.unity.addressables2.2/api/UnityEngine.ResourceManagement.AsyncOperations.AsyncOperationHandle.html) 实例提供以下方式获取进度更新 [AsyncOperationHandle.PercentComplete](https://docs.unity3d.com/Packages/com.unity.addressables2.2/api/UnityEngine.ResourceManagement.AsyncOperations.AsyncOperationHandle.PercentComplete.html#UnityEngine_ResourceManagement_AsyncOperations_AsyncOperationHandle_PercentComplete)报告已完成子操作的百分比。例如如果一个操作使用六个子操作来执行其任务当其中三个操作完成时PercentComplete 指示整个操作完成了 50%不考虑每个操作加载的数据量。[AsyncOperationHandle.GetDownloadStatus](https://docs.unity3d.com/Packages/com.unity.addressables2.2/api/UnityEngine.ResourceManagement.AsyncOperations.AsyncOperationHandle.GetDownloadStatus.html#UnityEngine_ResourceManagement_AsyncOperations_AsyncOperationHandle_GetDownloadStatus)返回一个[DownloadStatus](https://docs.unity3d.com/Packages/com.unity.addressables2.2/api/UnityEngine.ResourceManagement.AsyncOperations.DownloadStatus.html)结构报告总下载大小的百分比。例如如果一个操作有六个子操作但第一个操作代表总下载大小的 50%则当第一个操作完成时GetDownloadStatus 指示操作完成了 50%。 以下示例展示了如何使用 GetDownloadStatus 检查状态并在下载过程中分发进度事件 using System.Collections; using UnityEngine; using UnityEngine.AddressableAssets; using UnityEngine.Events; using UnityEngine.ResourceManagement.AsyncOperations;internal class PreloadWithProgress : MonoBehaviour {public string preloadLabel preload;public UnityEventfloat ProgressEvent;public UnityEventbool CompletionEvent;private AsyncOperationHandle downloadHandle;IEnumerator Start(){downloadHandle Addressables.DownloadDependenciesAsync(preloadLabel, false);float progress 0;while (downloadHandle.Status AsyncOperationStatus.None){float percentageComplete downloadHandle.GetDownloadStatus().Percent;if (percentageComplete progress * 1.1) // 每 10% 或左右报告一次{progress percentageComplete; // 更准确的百分比ProgressEvent.Invoke(progress);}yield return null;}CompletionEvent.Invoke(downloadHandle.Status AsyncOperationStatus.Succeeded);downloadHandle.Release(); // 释放操作句柄} }要了解加载一个或多个资源需要下载多少数据可以调用 [Addressables.GetDownloadSizeAsync](https://docs.unity3d.com/Packages/com.unity.addressables2.2/api/UnityEngine.AddressableAssets.Addressables.GetDownloadSizeAsync.html) AsyncOperationHandlelong getDownloadSize Addressables.GetDownloadSizeAsync(key);已完成操作的 Result 是必须下载的字节数。如果 Addressables 已缓存所有必需的 AssetBundles则 Result 为零。 在读取 Result 对象后总是释放下载操作句柄。如果不需要访问下载操作的结果可以通过将 autoReleaseHandle 参数设置为 true 来自动释放句柄如以下示例所示 using System.Collections; using UnityEngine; using UnityEngine.AddressableAssets;internal class Preload : MonoBehaviour {public IEnumerator Start(){yield return Addressables.DownloadDependenciesAsync(preload, true);} }清除依赖项缓存Clear the dependency cache 如果要清除 Addressables 缓存的任何 AssetBundles可以调用 [Addressables.ClearDependencyCacheAsync](https://docs.unity3d.com/Packages/com.unity.addressables2.2/api/UnityEngine.AddressableAssets.Addressables.ClearDependencyCacheAsync.html)。此方法会清除与键标识的资源相关的缓存 AssetBundles 以及包含这些资源依赖项的任何捆绑包。 ClearDependencyCacheAsync 仅清除与指定键相关的资源包。如果更新内容目录使键不再存在或不再依赖于相同的 AssetBundles那么这些捆绑包将保留在缓存中直到根据 cache settings 过期。 要清除所有 AssetBundles可以使用 UnityEngine.Caching 类中的方法。 从多个项目加载内容Load Content from Multiple Projects 如果你在处理多个项目例如一个跨多个 Unity 项目拆分的大型项目可以使用 [Addressables.LoadContentCatalogAsync](https://docs.unity3d.com/Packages/com.unity.addressables2.2/manual/LoadContentCatalogAsync.html) 将不同项目中的代码和内容链接在一起。 设置多个项目 要创建多项目设置请确保以下几点 每个项目使用相同版本的 Unity 编辑器。每个项目使用相同版本的 Addressables 包。 项目可以包含你需要的任何资源和代码。其中一个项目必须是你的主项目main project或源项目source project这是你构建和部署游戏二进制文件的项目。通常源项目主要包含代码而几乎没有内容。主要项目中的内容至少包括一个启动场景。你可能希望包括在任何 AssetBundles 下载和缓存之前需要本地化的场景以提高性能。 辅助项目Secondary projects则相反主要包含内容而几乎没有代码。这些项目需要启用所有远程 Addressable 组和构建 Remote Catalog 。内置到这些项目中的任何本地数据不能在源项目的应用程序中加载。非关键场景可以位于这些项目中并在需要时由主项目下载。 处理多个项目 一旦设置好项目工作流程通常如下 为所有辅助项目构建远程内容Build Remote Content。为源项目构建 Addressables 内容。启动源项目的 Play 模式或构建源项目的二进制文件。在源项目中使用[Addressables.LoadContentCatalogAsync](https://docs.unity3d.com/Packages/com.unity.addressables2.2/manual/LoadContentCatalogAsync.html)加载其他各种项目的 Remote Catalog 。正常进行游戏运行时操作。现在目录已加载Addressables 可以从这些位置加载资源。 建议在源项目中本地构建最少量的内容。每个项目都是独特的有独特的需求但建议在出现互联网连接问题或其他各种问题时拥有一小部分需要的内容以运行游戏。 处理内置built in资源和着色器 Addressables 为每一组 Addressables 玩家数据构建一个 Unity 内置资源包。这意味着当加载多个在辅助项目中构建的 AssetBundles 时可能会同时加载多个内置包。 根据你的具体情况可能需要在AddressableAssetSettings对象上使用内置包命名前缀。每个内置包需要与其他项目中构建的内置包命名不同。如果命名没有不同你会收到以下错误 The AssetBundle [bundle] cant be loaded because another AssetBundle with the same files is already loaded.
http://www.tj-hxxt.cn/news/232621.html

相关文章:

  • 利用第三方做网站永久发布地址跨境购网站建设
  • 珠海做网站wordpress教育类主题
  • 移动网站建设书籍推荐电子商务平台经营者所具备的功能
  • 企业网站建设制作设计哪家最专业小米官网页面
  • 网站的跳出率wordpress视屏
  • 网站设计简单吗网站建设方案平台
  • 如何在虚拟机中建设网站wordpress windows 伪静态
  • 昨天正常的网站突然显示建设中网站开发使用的工具
  • 建设部招标网 官方网站wordpress主题移动
  • 加强网站建设工作德州建设网站
  • 北京专业响应式网站建设怎么建设一个人自己网站
  • 腾讯云服务器搭建网站多少钱一个网站
  • 深圳网站建设开发哪家好免费制作视频的软件有哪些
  • 南昌公司建设网站费用怎样开通微信小程序卖东西
  • 做电容元器件的网站有哪些阿里巴巴国际站入驻费用
  • 公司网站建设服务公司网站制作公司网站建设
  • 校园二手市场网站建设百度手机应用市场
  • 网站vi设计公司咸阳网站建设公司哪家好
  • 做网站之前要备案是什么意思金融街做网站的公司
  • 广西城乡和建设厅网站免费申请etc
  • 网站设计优缺点网站上传照片失败
  • 网站设计模板html手机电商网站模板
  • 做网站找模版好吗中铁建设登录入口
  • 织梦做的网站怎么添加关键词asp与sql做网站
  • 中学生做的网站有哪些外贸站群
  • 网站建设技术网站建设wordpress shortcode 插件
  • 如何建立公司网站招标wordpress dz
  • 3 建设营销型网站流程图最好用的企业网站cms
  • 建站网址怎么改如何做某网站的移动客户端开发
  • 网站建设公司工作室代理记账一个月多少钱一个月