ue3d理解Unity场景加载和初始化时机

理解Unity场景加载和初始化时机

分类:
ue3d - 理解Unity场景加载和初始化时机

本文将介绍Unity中的场景加载和初始化时机,介绍了如何使用SceneManager(场景管理)和Addressables正确控制此行为。

场景负载

使用SceneManager和Addressables API将场景加载到Unity中,加载场景可以分解为加载场景本身以及加载和初始化该场景中存在的资产的过程。

加载场景本身时,不会调用场景中存在的每个组件的Awake等。此外,此时SceneManager.SetActiveScene在尝试激活此场景时遇到错误,也可以说是多场景编辑时进行Unload Scene,变成未加载的状态。

ue3d - 理解Unity场景加载和初始化时机

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

ue3d - 理解Unity场景加载和初始化时机

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中的场景加载和初始化时机的全部内容,如果你有任何反馈,请随时在本页面下方留言。

相关信息

  • 类型:知识
  • 字数:424
  • 字符:3564
  • 适用软件:Unity
  • 说明:无
  • 编号:161119

热门内容

提示:3D天堂作为服务提供者,尊重网络版权及知识产权,对某些行为的发生不具备充分的监控能力,若无意间侵犯到您的权利,请 联系我们,我们会在收到信息后尽快给予处理。

本站文章版权归本站自创作者所有,未经允许不得转载!