Unity framework learning--scene switching manager

Activity scene

Game objects instantiated using scripts are generated in the active scene.

Which scene is the active scene, the current skybox will use the skybox of that scene.

Only one scene can be the active scene.

Right-click a scene in the Hierarchy and click "Set Active Scene" to manually set this scene as the active scene. You can also use the SceneManager.SetActiveScene method to set a loaded scene as the active scene.

Asynchronous loading

AsyncOperation related code should be written in a coroutine.

AsyncOperation object name = SceneManager.LoadSceneAsync (string scene name)
turns on asynchronous loading of scenes and stores asynchronous loading information in AsyncOperation objects.

AsyncOperation type object.allowSceneActivation
returns a bool type, indicating whether to allow the scene to be activated immediately after the scene is loaded.
A value of true means that once the scene is loaded asynchronously, the scene will be activated immediately.
A value of false means that the scene will not be activated even if the scene is loaded. The scene will not be activated until the value of this variable is changed to true again using code.

AsyncOperation type object.progress
returns float type, ranging from 0-1. Indicates the progress of asynchronous loading, starting with 0 and completing with 1.
Note: When the value of the AsyncOperation variable .allowSceneActivation is false, the value of this parameter will be stuck at 0.9 at most until the value of the AsyncOperation variable .allowSceneActivation becomes true. This The value of the parameter will become 1

AsyncOperation type object.isDone
returns bool type. Indicates whether the asynchronous loading is completed. The value is true if completed, false if not completed.
When the value of AsyncOperation type object.progress is 1, the value of this variable is true at this time, but this will activate a new new scene. It is generally difficult to observe that AsyncOperation type object.isDone is true.

AsyncOperation type object.priority
returns int type, used to set the priority of asynchronous operations.
When multiple asynchronous operations are queued, the asynchronous operation with a higher priority will be executed first. But if the asynchronous operation is started on a background thread, changing the priority has no effect.

AsyncOperation.completed
is an Action event with an AsyncOperation parameter. The AsyncOperation parameter stores the information of this asynchronous loading.
When the asynchronous loading is completed, that is, when the value of AsyncOperation type object.isDone is true, this event will be executed once.
 

LoadSceneManager code

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.Events;

/// <summary>
/// 切换场景的管理器
/// </summary>
public class LoadSceneManager : SingletonPatternBase<LoadSceneManager>
{
    /// <summary>
    /// 重新切换当前场景
    /// </summary>
    public void LoadActiveScene()
    {
        SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex);
    }

    /// <summary>
    /// 切换到下一个场景,是否场景循环,最后一个场景切换是切换为第一个场景
    /// </summary>
    public void LoadNextScene(bool isCyclical=false)
    {
        int buildIndex = SceneManager.GetActiveScene().buildIndex + 1;

        //检测要切换的新场景的下标是否越界     这个参数的意思是BuildSettings中的场景总数
        if (buildIndex > SceneManager.sceneCountInBuildSettings-1)
        {
            if (isCyclical)
                buildIndex = 0;
            else
            {
                Debug.LogWarning($"加载场景失败!要加载的场景的索引是{buildIndex},越界了");
                return;
            }
        }

        SceneManager.LoadScene(buildIndex);
    }

    /// <summary>
    /// 加载上一个场景,包括可选择的场景循环功能
    /// </summary>
    public void LoadPreviousScene(bool isCyslical=false)
    {
        int buildIndex = SceneManager.GetActiveScene().buildIndex - 1;

        if (buildIndex < 0)
        {
            if (isCyslical)
            {
                buildIndex = SceneManager.sceneCountInBuildSettings - 1;
            }
            else
            {
                Debug.LogWarning($"加载场景失败!要加载的场景索引是{buildIndex},越界了!");
                return;
            }
        }

        SceneManager.LoadScene(buildIndex);
    }

    /// <summary>
    /// 异步加载场景  根据名字来切换场景
    /// </summary>
    public void LoadSceneAsync(string sceneName, UnityAction<float> loading = null,
        UnityAction<AsyncOperation> completed = null, bool setActiveAfterCompleted = true, LoadSceneMode mode = LoadSceneMode.Single)
    {
        MonoManager.Instance.StartCoroutine(LoadSceneCoroutine(sceneName, loading, completed, setActiveAfterCompleted, mode));
    }

    IEnumerator LoadSceneCoroutine(string sceneName, UnityAction<float> loading = null,
        UnityAction<AsyncOperation> completed = null, bool setActiveAfterCompleted = true, LoadSceneMode mode = LoadSceneMode.Single)
    {
        //开始加载资源
        AsyncOperation asyncOperation = SceneManager.LoadSceneAsync(sceneName, mode);

        asyncOperation.allowSceneActivation = false;  //资源加载最多到0.9

        //等待资源加载完毕
        while (asyncOperation.progress < 0.9f)
        {
            loading?.Invoke(asyncOperation.progress);
            yield return null;
        }

        //当asyncOperation.allowSceneActivation 为false,则asyncOperation.Progress最多只能到达0.9
        //我们人为把它们凑成1,可以方便外部进度条的显示
        loading?.Invoke(1);

        asyncOperation.allowSceneActivation = setActiveAfterCompleted;

        //加载资源完毕后执行的逻辑
        completed?.Invoke(asyncOperation);
    }

    /// <summary>
    /// 异步加载场景 根据索引来切换场景
    /// </summary>
    public void LoadSceneAsync(int sceneIndex,UnityAction<float>loading=null, 
        UnityAction completed = null,bool setActiveAfterCompleted=true, LoadSceneMode mode = LoadSceneMode.Single)
    {
        MonoManager.Instance.StartCoroutine(LoadSceneCoroutine(sceneIndex,loading, completed,setActiveAfterCompleted, mode));
    }

    IEnumerator LoadSceneCoroutine(int sceneIndex, UnityAction<float> loading = null,
        UnityAction completed = null, bool setActiveAfterCompleted = true, LoadSceneMode mode = LoadSceneMode.Single)
    {
        //开始加载资源
        AsyncOperation asyncOperation = SceneManager.LoadSceneAsync(sceneIndex, mode);

        asyncOperation.allowSceneActivation = false;  //资源加载最多到0.9

        //等待资源加载完毕
        while (asyncOperation.progress < 0.9f)
        {
            loading?.Invoke(asyncOperation.progress);
            yield return null;
        }

        //当asyncOperation.allowSceneActivation 为false,则asyncOperation.Progress最多只能到达0.9
        //我们人为把它们凑成1,可以方便外部进度条的显示
        loading?.Invoke(1);

        asyncOperation.allowSceneActivation = setActiveAfterCompleted;

        //加载资源完毕后执行的逻辑
        completed?.Invoke();
    }


}

test script

[MenuItem("我的菜单/同步切换场景/重新切换到上一个场景")]
    static void Method3()
    {
        LoadSceneManager.Instance.LoadPreviousScene();
    }

    [MenuItem("我的菜单/异步切换场景/重新切换到场景1")]
    static void Method4()
    {
        LoadSceneManager.Instance.LoadSceneAsync("New Scene 1", (obj) =>
         {
             Debug.Log("加载进度是:" + obj * 100 + "%");
         }, (obj) =>
         {
             Debug.Log("加载完成了!");
         });
    }

Unity Scene class (scene class)

Objects of the Scene class are used to store scene information.

Scene type object.buildIndex
returns an int type, indicating the index of the scene in the Build Settings window.
If the scene is an invalid scene, the value of this variable is -1.
If the scene is a scene loaded through AssetBundle, the value of this variable is also -1.

Scene type object.isDirty
returns bool type, indicating whether the scene has been modified.
When we modify a scene in editor mode but do not save it, the value of this variable is true. Once the scene is saved, the value of this variable is false

Scene type object.isLoaded
returns true if the scene has been loaded. If the scene has not been loaded or has not been loaded, return false

Scene type object.name
returns a string type, indicating the name of the scene. The end does not contain the suffix .unity,
which is its name in the Project window.
Note: The scene must have been loaded for this variable to correctly return its scene name. If the scene has not been loaded or has not been loaded, the returned value is "Null"

Scene object.path
returns a string type, indicating the path of the scene, with the suffix .unity at the end.
For example:
Assets/AssetBundleAssets/Scenes/TestScenes/Test.unity

Scene type object.rootCount
returns an int type, indicating the total number of Transform components on all root game objects in the scene.

Scene type object.GetRootGameObjects
returns GameObject[] type, representing all root game objects in the scene.
The hidden root game object will also be included, but the root game object of DontDestoryOnLoad will not be included.

Scene type object.IsValid
If a scene exists, it is a valid scene, and the value of this variable is true.
If a scene does not exist, it is an invalid scene, and the value of this variable is false.
Note: From EditorSceneManager.OpenScene The value of IsValid of the returned scene is false

The operator != can be used between two scene objects.
If the two scenes are different, it returns true, otherwise it returns false.

The operator == can be used between two scene objects.
If the two scenes are the same, it returns true, otherwise it returns false.

Unity SceneManager class (scene manager, used to load scenes and switch scenes)

First drag the scenes you want to jump into File-Build Settings

The namespace must be introduced first: using UnityEngine.SceneManagement;

SceneManager.sceneCount
The number of scenes currently loaded.

SceneManager.sceneCountInBuildSettings
The number of scenes that have been added to the Build Settings window.
If you are in editor mode, the scene that has been opened before entering play mode will also be included. If it is not manually dragged to the Build Settings window, it is also indexed in the Build Settings window, but we cannot see it. This index is greater than the maximum visible value of 1.

SceneManager.CreateScene(int scene name)
creates an empty scene, which will be superimposed on the current scene.
If the created scene has a duplicate name, an error will be reported.
The scene name can be seen in the Hierarchy window.
If you want to create a scene while editing, for example when creating an editor script or tool, you should use EditorSceneManager.NewScene

SceneManager.CreateScene(string scene name, CreateSceneParameters various parameters for creating the scene)
creates an empty scene, which will be superimposed on the current scene.
If the created scene has a duplicate name, an error will be reported.
The scene name can be seen in the Hierarchy window.
If you want to create a scene while editing, for example when creating an editor script or tool, you should use EditorSceneManager.NewScene

SceneManager.GetActiveScene()
returns a Scene object, representing information about the current scene.

SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex);
Use synchronization to switch to the current scene again.

SceneManager.GetActiveScene().buildIndex+1 represents the index of the next scene in the Build Settings window.

SceneManager.GetActiveScene().name
string type. Indicates the name of the current scene. Can be used with SceneManager.LoadScene to reload the current scene

SceneManager.GetSceneAt(int index)
returns information about the scene at the specified index in the list of currently loaded scenes.
The index must be greater than or equal to 0, and the minimum is 0. If it is a negative number or the index is out of bounds, an error will be reported.

SceneManager.GetSceneByBuildIndex (int index of the scene in the Build Settings window)
returns the scene information in the Build Settings based on the passed in index.
The scene must be in the Build Settings window and currently loaded for its information to be returned. Otherwise, an invalid Scene object will be returned.
The index must be greater than or equal to 0, and the minimum is 0. If it is a negative number or the index is out of bounds, an error will be reported.

SceneManager.GetSceneByName(string scene name)
searches for the scene with the specified scene name in the currently loaded scene.
If found, a Scene object is returned, representing the information of this scene. If not found, an invalid Scene object is returned.
The scene name can be the last part of the name shown in the Build Settings window, in which case the first matching scene information will be returned.
The scene name can also be the path displayed in the Build Settings window, in which case the exact matching scene information will be returned.
Scene names are not case sensitive.
Scene names must not contain the .unity extension.

SceneManager.GetSceneByPath(string scene path)
finds the scene with the specified resource path in the currently loaded scene.
If found, a Scene object is returned, representing the information of this scene. If not found, an invalid Scene object is returned.
The path to the scene should be relative to the project folder, for example: "Assets/MyScenes/MyScene.unity"

SceneManager.LoadScene(int index of the scene in the Build Settings window, LoadSceneMode mode of loading the scene);
        synchronously load the scene at the specified index.
        The first parameter can be of string type, so that the specified scene will be loaded based on the scene name or scene path. At this time, the scene with this name is either placed in the Build Settings window in advance, or has been loaded using AssetBundle before, so that this method will be effective. If there are none, an error will be reported. Note: The scene name does not contain the .unity suffix. Also, the scene names should not have the same name. If the scene names have the same name, the first matching scene will be loaded. You can use the scene path, for example: Assets/AssetBundleAssets/Scenes/TestScenes/Scene1.unity.
        If you use LoadSceneMode.Single as the second parameter, it will automatically switch to the scene after loading. The original scene will be uninstalled. This is used by default.
        If LoadSceneMode.Additive is used as the second parameter, the scene will be superimposed on the original scene after loading. The original scene will not be uninstalled, and the active scene remains the original scene.
        Using this method to load a scene will not load immediately, but will start loading in the next frame. And because this method is synchronous, lags may occur. It is recommended to use the LoadSceneAsync method of asynchronous loading.

SceneManager.LoadSceneAsync (int the index of the scene in the Build Settings window, LoadSceneMode the mode of loading the scene);
        asynchronously loads the scene at the specified index.
        The first parameter can be of string type, so that the specified scene will be loaded based on the scene name or scene path. At this time, the scene with this name is either placed in the Build Settings window in advance, or has been loaded using AssetBundle before, so that this method will be effective. If there are none, an error will be reported. Note: The scene name does not contain the .unity suffix. Also, the scene names should not have the same name. If the scene names have the same name, the first matching scene will be loaded. You can use the scene path, for example: Assets/AssetBundleAssets/Scenes/TestScenes/Scene1.unity.
        If you use LoadSceneMode.Single as the second parameter, you can switch to the scene after loading, and the original scene will be unloaded. This is used by default.
        If LoadSceneMode.Additive is used as the second parameter, the scene can be superimposed on the original scene after loading. The original scene will not be uninstalled, and the active scene remains the original scene.
        Using this method to load a scene will not freeze the game. It is often used in conjunction with the progress bar in the scene. You can control the progress of the progress bar while loading the scene.
        The return value type of this method is AsyncOperation type. You can judge whether the asynchronous loading is completed based on the object of this type. For details, please refer to the AsyncOperation class.

SceneManager.MergeScenes(Scene scene 1, Scene scene 2)
will transfer all game objects in scene 1 to scene 2, and scene 1 will be unloaded.
Generally, this method may be used only when LoadSceneMode.Additive is used to load the scene.
Both scene 1 and scene 2 must be loaded scenes.
If the original scene 1 is the active scene, then after it is uninstalled, the first scene at the top of the Hierarchy window will become the active scene.
If the original scene 1 is not the active scene, the active scene will not change after it is uninstalled.

SceneManager.MoveGameObjectToScene(GameObject the game object to be moved, Scene moves to the scene)
moves a game object from the scene where it is located to the target scene.
Generally, this method may be used only when LoadSceneMode.Additive is used to load the scene.
The scene you want to move to must be a loaded scene.
If the game object to be moved is null, this method has no effect.
If the scene you move to has not been loaded, or is an invalid scene, an error will be reported.

SceneManager.SetActiveScene(Scene scene name)
sets the specified scene as the active scene.

SceneManager.UnloadSceneAsync(int scene index in the Build Settings window)
SceneManager.UnloadSceneAsync(string scene name or scene path)
SceneManager.UnloadSceneAsync(Scene scene object)
SceneManager.UnloadSceneAsync(int scene index in the Build Settings window, UnloadSceneOptions unload the scene options)
SceneManager.UnloadSceneAsync (string scene name or scene path, UnloadSceneOptions options to unload the scene)
SceneManager.UnloadSceneAsync (Scene scene object, UnloadSceneOptions options to unload the scene)
Destroy the specified scene and all game objects in this scene.
This method is only valid for scenes loaded using LoadSceneMode.Additive. If there is only one scene in the current game, this method is invalid and the console will report a yellow warning.
This method will not unload the scene resources in the memory. If you want to release the resources, you should call the Resources.UnloadUnusedAssets method after calling this method.
The type of the return value is the AsyncOperation type. You can use this object to determine whether the asynchronous operation is completed.

SceneManager.activeSceneChanged
UnityAction<Scene,Scene> type event.
This event will be executed once when the active scene changes.
The first parameter represents the original activity scene, and the second parameter represents the subsequent activity scene.

SceneManager.sceneLoaded
UnityAction<Scene,LoadSceneMode> type event.
This event will be executed every time a new scene is loaded.
The first parameter indicates the new scene to be loaded, and the second parameter indicates the loading mode of this scene.

SceneManager.sceneUnloaded
UnityAction<Scene> type event.
This event will be executed every time a scene is unloaded.
The parameter represents the unloaded scene object.

Guess you like

Origin blog.csdn.net/zaizai1007/article/details/132377762