Unity异步加载常用类AsyncOperation和ResourceRequest
基本用法
AsyncOperation
通常与场景加载一起使用。以下是一些常见的用法示例:
异步加载场景
using UnityEngine;
using UnityEngine.SceneManagement;
using System.Collections;
public class SceneLoader : MonoBehaviour
{
void Start()
{
// 启动异步加载场景
StartCoroutine(LoadSceneAsync("YourSceneName"));
}
IEnumerator LoadSceneAsync(string sceneName)
{
// 开始异步加载场景
AsyncOperation asyncOperation = SceneManager.LoadSceneAsync(sceneName);
// 禁用自动激活场景,以便可以手动激活
asyncOperation.allowSceneActivation = false;
// 等待加载完成
while (!asyncOperation.isDone)
{
// 输出加载进度
Debug.Log("Loading progress: " + (asyncOperation.progress * 100) + "%");
// 激活场景
if (asyncOperation.progress >= 0.9f)
{
Debug.Log("Press space to continue...");
if (Input.GetKeyDown(KeyCode.Space))
{
asyncOperation.allowSceneActivation = true;
}
}
yield return null;
}
Debug.Log("Scene loaded!");
}
}
详细解释
SceneManager.LoadSceneAsync(sceneName)
:开始异步加载场景,并返回AsyncOperation
对象。asyncOperation.allowSceneActivation
:控制场景是否自动激活。如果设置为false
,场景将加载到 90% 后停止,直到手动激活。asyncOperation.isDone
:检查异步操作是否完成。asyncOperation.progress
:获取加载进度,范围从 0.0 到 1.0。
管理异步加载
在许多情况下,您可能需要在加载过程中显示加载进度条或其他 UI 元素。这可以通过 asyncOperation.progress
来实现:
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
using System.Collections;
public class SceneLoaderWithProgress : MonoBehaviour
{
public Slider progressBar;
void Start()
{
// 启动异步加载场景
StartCoroutine(LoadSceneAsync("YourSceneName"));
}
IEnumerator LoadSceneAsync(string sceneName)
{
// 开始异步加载场景
AsyncOperation asyncOperation = SceneManager.LoadSceneAsync(sceneName);
// 禁用自动激活场景,以便可以手动激活
asyncOperation.allowSceneActivation = false;
// 等待加载完成
while (!asyncOperation.isDone)
{
// 更新进度条
progressBar.value = asyncOperation.progress;
// 激活场景
if (asyncOperation.progress >= 0.9f)
{
progressBar.value = 1.0f;
Debug.Log("Press space to continue...");
if (Input.GetKeyDown(KeyCode.Space))
{
asyncOperation.allowSceneActivation = true;
}
}
yield return null;
}
Debug.Log("Scene loaded!");
}
}
其他异步操作
AsyncOperation
不仅仅用于场景加载,还可以用于其他异步操作,例如资源加载:
异步加载资源
using UnityEngine;
using System.Collections;
public class ResourceLoader : MonoBehaviour
{
void Start()
{
// 启动异步加载资源
StartCoroutine(LoadResourceAsync("YourResourceName"));
}
IEnumerator LoadResourceAsync(string resourceName)
{
// 开始异步加载资源
ResourceRequest resourceRequest = Resources.LoadAsync(resourceName);
// 等待加载完成
while (!resourceRequest.isDone)
{
Debug.Log("Loading progress: " + (resourceRequest.progress * 100) + "%");
yield return null;
}
// 获取加载的资源
Object loadedResource = resourceRequest.asset;
Debug.Log("Resource loaded!");
// 使用加载的资源
// 例如:Instantiate(loadedResource);
}
}
详细解释
Resources.LoadAsync(resourceName)
:开始异步加载资源,并返回ResourceRequest
对象,该对象是AsyncOperation
的子类。resourceRequest.isDone
:检查异步资源加载是否完成。resourceRequest.progress
:获取加载进度,范围从 0.0 到 1.0。resourceRequest.asset
:获取加载的资源。
总结
AsyncOperation
是 Unity 中处理异步操作的重要工具。通过理解和使用 AsyncOperation
,你可以在不阻塞主线程的情况下加载场景和资源,从而创建更流畅的游戏体验。
ResourceRequest
ResourceRequest
是 Unity 中用于异步加载资源的类。它是 AsyncOperation
的子类,允许你在不阻塞主线程的情况下加载资源。ResourceRequest
通常用于从 Resources 文件夹中异步加载资源。
基本用法
以下是一个使用 ResourceRequest
类异步加载资源的基本示例:
using UnityEngine;
using System.Collections;
public class ResourceLoader : MonoBehaviour
{
void Start()
{
// 启动异步加载资源
StartCoroutine(LoadResourceAsync("YourResourceName"));
}
IEnumerator LoadResourceAsync(string resourceName)
{
// 开始异步加载资源
ResourceRequest resourceRequest = Resources.LoadAsync(resourceName);
// 等待加载完成
while (!resourceRequest.isDone)
{
Debug.Log("Loading progress: " + (resourceRequest.progress * 100) + "%");
yield return null;
}
// 获取加载的资源
Object loadedResource = resourceRequest.asset;
Debug.Log("Resource loaded!");
// 使用加载的资源
// 例如:Instantiate(loadedResource);
}
}
详细解释
Resources.LoadAsync(resourceName)
:开始异步加载资源,并返回一个ResourceRequest
对象。resourceName
是资源的路径,相对于 Resources 文件夹。resourceRequest.isDone
:检查异步资源加载是否完成。返回true
表示加载完成。resourceRequest.progress
:获取加载进度,范围从 0.0 到 1.0。resourceRequest.asset
:获取加载的资源,当isDone
为true
时,可以通过resourceRequest.asset
访问加载的资源。
示例场景
假设你有一个名为 "MyPrefab" 的预制体存储在 Resources 文件夹中,你希望异步加载并实例化该预制体:
using UnityEngine;
using System.Collections;
public class AsyncPrefabLoader : MonoBehaviour
{
void Start()
{
// 启动异步加载预制体
StartCoroutine(LoadAndInstantiatePrefab("MyPrefab"));
}
IEnumerator LoadAndInstantiatePrefab(string prefabName)
{
// 开始异步加载预制体
ResourceRequest resourceRequest = Resources.LoadAsync<GameObject>(prefabName);
// 等待加载完成
while (!resourceRequest.isDone)
{
Debug.Log("Loading progress: " + (resourceRequest.progress * 100) + "%");
yield return null;
}
// 获取加载的预制体
GameObject loadedPrefab = resourceRequest.asset as GameObject;
Debug.Log("Prefab loaded!");
// 实例化预制体
if (loadedPrefab != null)
{
Instantiate(loadedPrefab, Vector3.zero, Quaternion.identity);
}
}
}
等待多个资源加载
如果你需要同时异步加载多个资源,可以使用多个 ResourceRequest
并等待它们全部完成:
using UnityEngine;
using System.Collections;
public class MultipleResourceLoader : MonoBehaviour
{
void Start()
{
// 启动异步加载多个资源
StartCoroutine(LoadMultipleResources());
}
IEnumerator LoadMultipleResources()
{
ResourceRequest request1 = Resources.LoadAsync("Resource1");
ResourceRequest request2 = Resources.LoadAsync("Resource2");
// 等待所有资源加载完成
while (!request1.isDone || !request2.isDone)
{
Debug.Log("Loading progress: Resource1 - " + (request1.progress * 100) + "%, Resource2 - " + (request2.progress * 100) + "%");
yield return null;
}
// 获取加载的资源
Object resource1 = request1.asset;
Object resource2 = request2.asset;
Debug.Log("All resources loaded!");
// 使用加载的资源
// 例如:Instantiate(resource1); Instantiate(resource2);
}
}
错误处理
在加载资源时,可能会遇到加载失败的情况。虽然 ResourceRequest
本身没有直接的错误处理机制,但你可以通过检查 resourceRequest.asset
是否为 null
来处理加载失败的情况:
using UnityEngine;
using System.Collections;
public class SafeResourceLoader : MonoBehaviour
{
void Start()
{
// 启动异步加载资源
StartCoroutine(LoadResourceAsync("YourResourceName"));
}
IEnumerator LoadResourceAsync(string resourceName)
{
// 开始异步加载资源
ResourceRequest resourceRequest = Resources.LoadAsync(resourceName);
// 等待加载完成
while (!resourceRequest.isDone)
{
Debug.Log("Loading progress: " + (resourceRequest.progress * 100) + "%");
yield return null;
}
// 获取加载的资源
Object loadedResource = resourceRequest.asset;
if (loadedResource == null)
{
Debug.LogError("Failed to load resource: " + resourceName);
}
else
{
Debug.Log("Resource loaded!");
// 使用加载的资源
// 例如:Instantiate(loadedResource);
}
}
}
总结
ResourceRequest
是 Unity 中处理异步资源加载的有用工具。通过理解和使用 ResourceRequest
,你可以在不阻塞主线程的情况下加载资源,从而提高游戏的性能和用户体验。