当前位置:   article > 正文

Unity3D 11-SceneManager场景管理用法总结

scenemanager

一、Unity关卡

Unity 使用过程中关卡加载和卸载是大多数三维引擎都要提供的基本功能。
因为关卡切换在游戏中非常常用。
在之前的版本中Unity的关卡切换使用的是:

Application.loadedLevel();
  • 1

看看Application类,此时这个类的功能比较繁杂,比较多。只看与关卡相关的:

 [Obsolete("Use SceneManager.LoadScene")]
        public static void LoadLevel(string name);

        [Obsolete("Use SceneManager.LoadScene")]
        public static void LoadLevel(int index);

        [Obsolete("Use SceneManager.LoadScene")]
        public static void LoadLevelAdditive(string name);

        [Obsolete("Use SceneManager.LoadScene")]
        public static void LoadLevelAdditive(int index);
  //
        // 摘要:
        //     ///
        //     Unloads all GameObject associated with the given scene. Note that assets are
        //     currently not unloaded, in order to free up asset memory call Resources.UnloadAllUnusedAssets.
        //     ///
        //
        // 参数:
        //   index:
        //     Index of the scene in the PlayerSettings to unload.
        //
        //   scenePath:
        //     Name of the scene to Unload.
        //
        // 返回结果:
        //     ///
        //     Return true if the scene is unloaded.
        //     ///
        [Obsolete("Use SceneManager.UnloadScene")]
        public static bool UnloadLevel(string scenePath);
        //
        // 摘要:
        //     ///
        //     Unloads all GameObject associated with the given scene. Note that assets are
        //     currently not unloaded, in order to free up asset memory call Resources.UnloadAllUnusedAssets.
        //     ///
        //
        // 参数:
        //   index:
        //     Index of the scene in the PlayerSettings to unload.
        //
        //   scenePath:
        //     Name of the scene to Unload.
        //
        // 返回结果:
        //     ///
        //     Return true if the scene is unloaded.
        //     ///
        [Obsolete("Use SceneManager.UnloadScene")]
        public static bool UnloadLevel(int index);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51

注解:
这是之前的Application中的关卡的加载和卸载。
当然现在在新版本(Unity5.3以上)中,有了新的变化,那就是SceneManager类了处理。

二、Untiy的SceneManager类

自从Unity5.3版本,Unity 的关卡切换就添加了新的SceneManager的类来处理。
当然要安装过了Unity文档帮助,并且给下面路径一样,就可以知道在本地打开。
本地链接:
file:///C:/Program%20Files/Unity5.3.0/Editor/Data/Documentation/en/Manual/UpgradeGuide53.html
也可以在Unity中搜索SceneManager来查看。

#region 程序集 UnityEngine, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
// H:\Unity\UnityProject\ShiftLevels\Library\UnityAssemblies\UnityEngine.dll
#endregion

using UnityEngine.Internal;

namespace UnityEngine.SceneManagement
{
    //
    // 摘要:
    //     ///
    //     Scene management at run-time.
    //     ///
    public class SceneManager
    {
        public SceneManager();


        public static int sceneCount { get; }
        //

        public static int sceneCountInBuildSettings { get; }


        public static Scene GetActiveScene();

        public static Scene[] GetAllScenes();
        // 参数:
        //   index:
        //     Index of the scene to get. Index must be greater than or equal to 0 and less
        //     than SceneManager.sceneCount.
        public static Scene GetSceneAt(int index);

        // 返回结果:
        //     ///
        //     The scene if found or an invalid scene if not.
        //     ///
        public static Scene GetSceneByName(string name);

        //     Searches all scenes added to the SceneManager for a scene that has the given
        //     asset path.
        //     ///
        //
        // 参数:
        //   scenePath:
        //     Path of the scene. Should be relative to the project folder. Like: "AssetsMyScenesMyScene.unity".
        public static Scene GetSceneByPath(string scenePath);
        [ExcludeFromDocs]
        public static void LoadScene(int sceneBuildIndex);
        [ExcludeFromDocs]
        public static void LoadScene(string sceneName);

        // 参数:
        //   sceneName:
        //     Name of the scene to load.
        //
        //   sceneBuildIndex:
        //     Index of the scene in the Build Settings to load.
        //
        //   mode:
        //     Allows you to specify whether or not to load the scene additively. See SceneManagement.LoadSceneMode
        //     for more information about the options.
        public static void LoadScene(int sceneBuildIndex, [DefaultValue("LoadSceneMode.Single")] LoadSceneMode mode);

        // 参数:
        //   sceneName:
        //     Name of the scene to load.
        //
        //   sceneBuildIndex:
        //     Index of the scene in the Build Settings to load.
        //
        //   mode:
        //     Allows you to specify whether or not to load the scene additively. See SceneManagement.LoadSceneMode
        //     for more information about the options.
        public static void LoadScene(string sceneName, [DefaultValue("LoadSceneMode.Single")] LoadSceneMode mode);
        [ExcludeFromDocs]
        public static AsyncOperation LoadSceneAsync(int sceneBuildIndex);
        [ExcludeFromDocs]
        public static AsyncOperation LoadSceneAsync(string sceneName);

        // 参数:
        //   sceneName:
        //     Name of the scene to load.
        //
        //   sceneBuildIndex:
        //     Index of the scene in the Build Settings to load.
        //
        //   mode:
        //     If LoadSceneMode.Single then all current scenes will be unloaded before loading.
        public static AsyncOperation LoadSceneAsync(int sceneBuildIndex, [DefaultValue("LoadSceneMode.Single")] LoadSceneMode mode);

        // 参数:
        //   sceneName:
        //     Name of the scene to load.
        //
        //   sceneBuildIndex:
        //     Index of the scene in the Build Settings to load.
        //
        //   mode:
        //     If LoadSceneMode.Single then all current scenes will be unloaded before loading.
        public static AsyncOperation LoadSceneAsync(string sceneName, [DefaultValue("LoadSceneMode.Single")] LoadSceneMode mode);
        //

        // 参数:
        //   sourceScene:
        //     The scene that will be merged into the destination scene.
        //
        //   destinationScene:
        //     Existing scene to merge the source scene into.
        public static void MergeScenes(Scene sourceScene, Scene destinationScene);
        //
        // 摘要:
        //     ///
        //     Move a GameObject from its current scene to a new scene. /// It is required that
        //     the GameObject is at the root of its current scene.
        //     ///
        //
        // 参数:
        //   go:
        //     GameObject to move.
        //
        //   scene:
        //     Scene to move into.
        public static void MoveGameObjectToScene(GameObject go, Scene scene);
        //

        // 返回结果:
        //     ///
        //     Returns false if the scene is not loaded yet.
        //     ///
        public static bool SetActiveScene(Scene scene);

        //     ///
        public static bool UnloadScene(string sceneName);
        //
        // 摘要:
        //     ///
        //     Unloads all GameObjects associated with the given scene. Note that assets are
        //     currently not unloaded, in order to free up asset memory call Resources.UnloadAllUnusedAssets.
        //     ///
        //
        // 参数:
        //   sceneBuildIndex:
        //     Index of the scene in the Build Settings to unload.
        //
        //   sceneName:
        //     Name of the scene to unload.
        //
        // 返回结果:
        //     ///
        //     Returns true if the scene is unloaded.
        //     ///
        public static bool UnloadScene(int sceneBuildIndex);
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155

三、SceneManager对于获取场景的一些操作

(一)
SceneManager
class in UnityEngine.SceneManagement
描述:运行时的场景管理。
静态变量sceneCount: 当前加载的场景的总数。
前加载的场景的数量将被返回。
sceneCountInBuildSettings : 在BuildSettings的号码。

(二)
CreateScene:在运行时创建一个空的新场景,使用给定的名称。
在运行时创建一个空的新场景,使用给定的名称。
新的场景将开放相加到层次与现有已经打开的场景。新场景的路径将是空的。此函数用于在运行时创建场景。创建一个场景编辑时间(例如,使编辑脚本或工具需要创建场景时),使用editorscenemanager.newscene。

(三)
public static SceneManagement.Scene GetActiveScene()
现场的活动场景。
描述:获取当前活动场景。
当前活动的场景将被用来作为目标由脚本实例化新的游戏对象现场。

using UnityEngine;
using UnityEngine.SceneManagement;

public class GetActiveSceneExample : MonoBehaviour
{
    void Start()
    {
        Scene scene = SceneManager.GetActiveScene();

        Debug.Log("Active scene is '" + scene.name + "'.");
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

(四)
public static SceneManagement.Scene GetSceneAt(int index);
index:场景索引。指数必须大于或等于0和小于scenemanager.scenecount。

返回:
根据给定的参数返回一个场景引用。
获取现场在添加场景的场景管理器的列表索引:

using UnityEditor;
using UnityEditor.SceneManagement;
using UnityEngine.SceneManagement;
using UnityEngine;
public class Example
{
    // adds a menu item which gives a brief summary of currently open scenes
    [MenuItem("SceneExample/Scene Summary")]
    public static void ListSceneNames()
    {
        string output = "";
        if (SceneManager.sceneCount > 0)
        {
            for (int n = 0; n < SceneManager.sceneCount; ++n)
            {
                Scene scene = SceneManager.GetSceneAt(n);
                output += scene.name;
                output += scene.isLoaded ? " (Loaded, " : " (Not Loaded, ";
                output += scene.isDirty ? "Dirty, " : "Clean, ";
                output += scene.buildIndex >=0 ? " in build)\n" : " NOT in build)\n";
            }
        }
        else
        {
            output = "No open scenes.";
        }
        EditorUtility.DisplayDialog("Scene Summary",output, "Ok");
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29

(五)

public static SceneManagement.Scene GetActiveScene();
获取当前活动场景。
当前活动的场景将被用来作为目标由脚本实例化新对象。

using UnityEngine;
using UnityEngine.SceneManagement;

public class GetActiveSceneExample : MonoBehaviour
{
    void Start()
    {
        Scene scene = SceneManager.GetActiveScene();

        Debug.Log("Active scene is '" + scene.name + "'.");
    }
}

public static void LoadScene(int sceneBuildIndex, SceneManagement.LoadSceneMode mode = LoadSceneMode.Single);
public static void LoadScene(string sceneName, SceneManagement.LoadSceneMode mode = LoadSceneMode.Single);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

sceneName: 需发加载的场景名称或路径。

sceneBuildIndex:在“ Build Settings”加载中的场景的索引。

Mode:允许您指定是否要加载相加现场。见LoadScene模式有关选项的详细信息。
LoadSceneMode:在播放器加载一个场景时使用。
Single:关闭所有当前场景和加载一个新场景。
Additive:将场景添加到当前加载的场景中。
你可以使用这个异步版本:LoadSceneAsync。

using UnityEngine;
using UnityEngine.SceneManagement;

public class ExampleClass : MonoBehaviour {
    void Start () {
        // Only specifying the sceneName or sceneBuildIndex will load the scene with the Single mode
        SceneManager.LoadScene ("OtherSceneName", LoadSceneMode.Additive);
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

四、5.3的实现代码

上代码:

/**************************************************************************
Copyright:@maxdong
Author: maxdong
Date: 2017-07-04
Description:加载关卡,可以分组加载和卸载。使用Unity版本为5.3.0.
因为里面使用了场景管理的一个类,这个类在5.3.0以上版本才添加的。
测试操作:使用空格键来切换场景,然后间隔5秒后才开始卸载。
**************************************************************************/
using UnityEngine;
using System.Collections;
using UnityEngine.SceneManagement;

[System.Serializable]
public class LevelOrder
{

    [Header("每组关卡名称")]
    public string[] LevelNames;
}

public class ChangLevelsHasMain : MonoBehaviour
{
    [Header("所有关卡列表")]
    public LevelOrder[] levelOrder;
    private static int index;
    private int totalLevels = 0;
    private int levelOrderLength;

    void Start ()
    {
        for (int i = 0; i < levelOrder.Length; i++)
        {
            totalLevels += levelOrder[i].LevelNames.Length;
        }

        if (totalLevels != SceneManager.sceneCountInBuildSettings)
        {

        }
        levelOrderLength = levelOrder.Length;
    }

    // Update is called once per frame
    void Update ()
    {
        if (Input.GetKeyDown(KeyCode.Space))
        {
            bool isOk = LoadNextLevels();
            if (isOk)
            {
                InvokeRepeating("UnloadLastLevel", 2.0f, 5);
            }
        }
    }

    bool LoadNextLevels()
    {
        bool bResult = true;
        //index = index % levelOrderLength;
        if (index < 0 || index >= levelOrderLength)
        {
            bResult = false;
            return bResult;
        }

        int LoadTimes = levelOrder[index].LevelNames.Length;
        for (int i = 0; i < LoadTimes; i++)
        {
            SceneManager.LoadSceneAsync(levelOrder[index].LevelNames[i], LoadSceneMode.Additive);
        }
        return bResult;
    }

    void UnloadLastLevel()
    {
        if (index == 0)
        {
            index++;
            CancelInvoke("UnloadLastLevel");
            return;
        }
        // 上一組的關卡
        int TmpLast = (index - 1) >= 0 ? (index - 1) : levelOrderLength - 1;
        int LoadTimes = levelOrder[index].LevelNames.Length;
        for (int i = 0; i < LoadTimes; i++)
        {
            Scene Tmp = SceneManager.GetSceneByName(levelOrder[index].LevelNames[i]);
            if (!Tmp.isLoaded)
            {
                return;
            }
        }

        // 下一關卡全部加載完畢後,卸載之前關卡
        for (int i = 0; i < levelOrder[TmpLast].LevelNames.Length; i++)
        {
            SceneManager.UnloadScene(levelOrder[TmpLast].LevelNames[i]);
        }
        index++;
        CancelInvoke("UnloadLastLevel");
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102

就这样就可以了。
代码主要是按组来加载关卡,然后按组来卸载。
测试中,按下空格键来加载,每组关卡在一定时间后,(这里设置的5秒)自动卸载前一组关卡。这里主地图是不卸载的,会一直存在的。

怎么设置的呢?首先需要在Build setting中中把所有要处理的关卡放进来。要不就会在加载过程中报错。
如下图:
这里写图片描述

然后把代码挂在主地图的任意对象对象上就可以了.
这里写图片描述

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小丑西瓜9/article/detail/99763
推荐阅读
相关标签
  

闽ICP备14008679号