您的位置:首页 > 移动开发 > Unity3D

Unity5的关卡切换

2016-04-04 10:47 405 查看
本文章由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:\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);
}
}


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

三、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————–

若有问题,请随时联系!!

非常感谢!!

你在桥上看风景,我在楼里加班!

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: