
本文将介绍Unity中的场景加载和初始化时机,介绍了如何使用SceneManager(场景管理)和Addressables正确控制此行为。
场景负载
使用SceneManager和Addressables API将场景加载到Unity中,加载场景可以分解为加载场景本身以及加载和初始化该场景中存在的资产的过程。
加载场景本身时,不会调用场景中存在的每个组件的Awake等。此外,此时SceneManager.SetActiveScene在尝试激活此场景时遇到错误,也可以说是多场景编辑时进行Unload Scene,变成未加载的状态。

在此状态下,将能够在场景中的资产加载和初始化完成后访问它们。这可以说是多场景编辑时进行Load Scene的状态。

SceneManager.LoadScene
第一种是使用SceneManager.LoadScene同步加载场景的情况,此API同步加载并返回场景本身。
但是此时场景资源还没有加载,所以需要等待Scene.isLoaded变为true,如下所示:
using System.Collections;
using UnityEngine;
using UnityEngine.SceneManagement;
public class Example : MonoBehaviour
{
private IEnumerator Start()
{
// Load the scene itself synchronously
var scene = SceneManager.LoadScene("Test", new LoadSceneParameters(LoadSceneMode.Additive));
// At this point, Awake and Start of the components in the scene have not been called.
// SetActiveScene error
// Wait for the assets on the scene to load
yield return new WaitUntil(() => scene.isLoaded);
// At this point, Awake and Start of components in the scene have been called.
// You can also SetActiveScene
SceneManager.SetActiveScene(scene);
}
}
SceneManager.LoadSceneAsync
使用SceneManager.LoadSceneAsync时,行为会稍微简单一些。
如下所示,当AsyncOpretaionHandle指示完成时,场景中的资产初始化就完成了。
using System.Collections;
using UnityEditor;
using UnityEngine;
using UnityEngine.SceneManagement;
public class Example : MonoBehaviour
{
private IEnumerator Start()
{
// Load and initialize the scene itself and the assets on the scene
yield return SceneManager.LoadSceneAsync("Test", new LoadSceneParameters(LoadSceneMode.Additive));
// At this point, Awake and Start of components in the scene have been called
// You can also SetActiveScene
var scene = SceneManager.GetSceneByName("Test");
SceneManager.SetActiveScene(scene);
}
}
通过如下所示将(LoadSceneAsync)返回值设置为AsyncOperationfalse ,可以将其设置为未加载状态。
var op = SceneManager.LoadSceneAsync("Test", new LoadSceneParameters(LoadSceneMode.Additive));
op.allowSceneActivation = false;
yield return op;
Addressables.LoadSceneAsync
Addressables可以更好地控制这种行为。
首先,如果在加载时将参数activateOnLoad设置为true,如下所示,行为将一直执行到场景中的资产初始化。
using System.Collections;
using UnityEditor;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.SceneManagement;
public class Example : MonoBehaviour
{
private IEnumerator Start()
{
// When activateOnLoad is set to true (default value), the assets on the scene are initialized.
var op = Addressables.LoadSceneAsync("Test", LoadSceneMode.Additive, true);
yield return op;
// At this point, Awake and Start of components in the scene have been called
// You can also SetActiveScene
var scene = op.Result.Scene;
SceneManager.SetActiveScene(scene);
}
}
将此设置为false只会加载场景本身。
要初始化资产,需要调用SceneInstance的ActivateAsync,如下所示。
using System.Collections;
using UnityEditor;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.SceneManagement;
public class Example : MonoBehaviour
{
private IEnumerator Start()
{
// If you set activateOnLoad to false, only the scene itself is loaded.
var op = Addressables.LoadSceneAsync("Test", LoadSceneMode.Additive, false);
yield return op;
// At this point, Awake and Start of the components in the scene have not been called.
// Error when trying to SetActiveScene
// Load assets on scene
yield return op.Result.ActivateAsync();
// At this point, Awake and Start of components in the scene have been called
// You can also SetActiveScene
var scene = op.Result.Scene;
SceneManager.SetActiveScene(scene);
}
}
…
以上是3D天堂关于Unity中的场景加载和初始化时机的全部内容,如果你有任何反馈,请随时在本页面下方留言。