当我们的场景资源过大时,为了能够不影响玩家体验,就会使用异步加载。
官方文档:AsyncOperation - Unity 脚本 API
AsyncOperation的API
allowSceneActivation | 允许在场景准备就绪后立即激活场景。 |
isDone | 操作是否已完成?(只读) |
priority | Priority 允许您调整执行异步操作调用的顺序。 |
progress | 获取操作进度。(只读) |
异步加载的好处:
- 提高游戏性能:异步加载场景可以减少游戏的内存占用和加载时间。当使用异步加载时,游戏可以在后台加载场景,同时保持流畅的游戏运行。这样可以减少游戏卡顿和加载时间,提高游戏的性能和用户体验。
- 优化资源管理:异步加载场景可以更好地管理游戏资源。通过异步加载,你可以在需要时加载场景中的特定资源,而不必一次性加载所有资源。这样可以减少内存占用,并提高游戏的资源利用率。
- 实现无缝切换:异步加载场景可以实现无缝切换。例如,在游戏中实现关卡切换时,可以使用异步加载场景来加载下一个关卡,同时保持当前关卡的运行状态。这样可以实现平滑的过渡,避免游戏中断或加载时间过长的情况。
- 提高开发效率:异步加载场景可以提高开发效率。通过将场景的加载过程分为多个步骤,可以更好地管理和调试游戏逻辑。同时,异步加载场景也使得开发人员可以更快地预览和测试游戏的不同场景,加快开发迭代的速度。
下面是实现,代码都会注释,这里是最最简单的异步加载,一般来说我们都会配合进度条来实现异步加载,以给玩家更好的游戏体验
默认情况下,AsyncOperation.allowSceneActivation的值为true,即加载完成后场景会自动激活。如果需要在加载完成后手动激活场景,可以将allowSceneActivation设置为false,并在适当的时机手动调用AsyncOperation.allowSceneActivation = true来激活场景。
应在协程函数中设置和使用 AsyncOperation.allowSceneActivation。不能在 Awake 中设置和使用 AsyncOperation.allowSceneActivation,因为此函数不是协程。
1.update实现
using UnityEngine;
using System.Collections;
using UnityEngine.SceneManagement;
public class Loading : MonoBehaviour
{
//AsyncOperation 是 Unity 引擎中的一个类,在异步操作过程中使用,例如加载资源和场景等
//它可以查看异步的状态和进度
private AsyncOperation operation;
//调用--调用不一定要这样调用,很多不同地方都可以,这里是为了便于理解
private void Start()
{
//开启协程
StartCoroutine(AsyncLoad(2));
}
//异步加载需要用协程实现,其一unity不支持多线程,异步加载是指边运行当前场景
//边加载下一个场景的资源,当资源加载完毕,再切换场景
IEnumerator AsyncLoad(int scene)
{
//unity异步加载的API
operation = SceneManager.LoadSceneAsync(scene);
//不允许切场景
operation.allowSceneActivation = false;
yield return operation;
}
private void Update()
{
//不为空则开始检测进度
if (operation != null)
{
Debug.Log("当前进度:"+(operation.progress/0.9f));
//加载完毕
//这里注意:如果你需要实现进度条,那么一定要知道
//当进度到达90%时其实就不会再动了
if (operation.progress >= 0.9f)
{
//可以允许自动切场景了
operation.allowSceneActivation = true;
}
}
}
}
官方文档中说明了当allowSceneActivation = false时,进度会停在0.9,且isDone也为false。
2.while实现
using UnityEngine;
using System.Collections;
using UnityEngine.SceneManagement;
public class Loading : MonoBehaviour
{
//AsyncOperation 是 Unity 引擎中的一个类,在异步操作过程中使用,例如加载资源和场景等
//它可以查看异步的状态和进度
private AsyncOperation operation;
//调用--调用不一定要这样调用,很多不同地方都可以,这里是为了便于理解
private void Start()
{
//开启协程
StartCoroutine(AsyncLoad(2));
}
//异步加载需要用协程实现,其一unity不支持多线程,异步加载是指边运行当前场景
//边加载下一个场景的资源,当资源加载完毕,再切换场景
IEnumerator AsyncLoad(int scene)
{
//unity异步加载的API
operation = SceneManager.LoadSceneAsync(scene);
//将原本在update里的逻辑放到while中
//未完成
while(!operation.isDone)
{
float progress =operation.progress / 1.0f;
Debug.Log("当前进度: " + progress);
yield return null;
}
}
}
第二同样也可以手动激活,略微改下协程函数逻辑,不要使用isDone的API,因为要实现手动isDone必为false,所以它已经失效了。
无论是第一种还是第二种,都需要协程来实现,所以想到异步加载就应该想到协程
这里都是最简单的原理和使用,如果需要实现其他功能,只需要在框架上修改即可。
这里还介绍一个API,一般我们做异步加载为了防止进度溢出会使用
Mathf.Clamp01