• Unity5的关卡切换


    本文章由cartzhang编写,转载请注明出处。 所有权利保留。
    文章链接:http://blog.csdn.net/cartzhang/article/details/51055584
    作者:cartzhang

    一、Unity关卡

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

    Application.loadedLevel()


    看看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);

    这是之前的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:UnityUnityProjectShiftLevelsLibraryUnityAssembliesUnityEngine.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);
        }
    }

    注意的是这里面还有可以带对象来在关卡中移动的,还有穿越功能啊!!哈哈

    三、5.3的实现代码

    上代码:

    /**************************************************************************
    Copyright:@cartzhang
    Author: cartzhang
    Date: 2016-04-01
    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");
        }
    }
    

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

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

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

    四、测试结果

    随意做了几张地图,不那么好看。但是功能很明显。
    第一组:
    这里写图片描述
    第二组
    这里写图片描述
    第三组
    这里写图片描述

    参考

    file:///C:/Program%20Files/Unity5.3.0/Editor/Data/Documentation/en/Manual/UpgradeGuide53.html

    追加Github地址:https://github.com/cartzhang/ShiftLevels

    ————————–THE———END————–

    若有问题,请随时联系!!
    非常感谢!!
    你在桥上看风景,我在楼里加班!
    去看看

  • 相关阅读:
    TP5.1 查看具体版本
    require(): open_basedir restriction in effect. 解决方法
    解决php -v查看到版本于phpinfo()打印的版本不一致问题
    Session机制详解
    c# 获取项目的根目录
    会修电脑不会修收音机?-闲聊设计模式原则
    CSV格式数据如何导入SqlServer?
    CSV格式数据如何导入MySQL?
    反射—程序员的快乐 -08
    策略模式 是一种好策略 -07
  • 原文地址:https://www.cnblogs.com/qitian1/p/6461914.html
Copyright © 2020-2023  润新知