Appearance
场景系统常见的API
先记住命名空间
Unity 场景相关 API 大多在这里:
c
using UnityEngine.SceneManagement;你只要写场景切换,基本都要加这一行。
最常用 API
c
SceneManager.LoadScene("Level01");加载一个场景。最常用于:主菜单进入游戏、进入下一关、进入结算页。
c
SceneManager.LoadScene(1);通过 Build Settings 里的序号加载场景。序号从 0 开始。
c
SceneManager.GetActiveScene();获取当前正在运行的场景。最常用于:重开当前关。
c
SceneManager.LoadSceneAsync("Level01");异步加载场景。最常用于:大地图、加载进度条、Loading 页面。
c
SceneManager.LoadScene("Shop", LoadSceneMode.Additive);叠加加载场景。最常用于:弹出商店、加载 UI 层、分块地图。
c
SceneManager.UnloadSceneAsync("Shop");卸载一个已经叠加加载的场景。
c
DontDestroyOnLoad(gameObject);切换场景时,不销毁这个对象。常用于:音乐、GameManager、存档管理器。
案例 1:按钮从主菜单进入第一关
建一个脚本 SceneLoader.cs:
c
using UnityEngine;
using UnityEngine.SceneManagement;
public class SceneLoader : MonoBehaviour
{
public void LoadLevel01()
{
SceneManager.LoadScene("Level01");
}
}使用方法:
c
1. 创建 MainMenu 场景
2. 创建 Level01 场景
3. 把两个场景加入 File > Build Settings > Scenes In Build
4. 在 MainMenu 里创建一个 Button
5. 创建空物体 SceneLoader
6. 挂上 SceneLoader 脚本
7. Button 的 OnClick 绑定 SceneLoader.LoadLevel01点击按钮后,就会从 MainMenu 进入 Level01。
案例 2:重开当前关卡
c
using UnityEngine;
using UnityEngine.SceneManagement;
public class SceneLoader : MonoBehaviour
{
public void RestartCurrentScene()
{
Scene currentScene = SceneManager.GetActiveScene();
SceneManager.LoadScene(currentScene.name);
}
}这一句很关键:
c
Scene currentScene = SceneManager.GetActiveScene();它拿到当前场景,比如你现在在 Level03,它就拿到 Level03。
然后:
c
SceneManager.LoadScene(currentScene.name);重新加载自己。
适合:
c
玩家死亡
点击重新开始
时间耗尽
挑战失败案例 3:进入下一关
如果你的 Build Settings 是:
c
0 MainMenu
1 Level01
2 Level02
3 Level03可以这样写:
c
using UnityEngine;
using UnityEngine.SceneManagement;
public class SceneLoader : MonoBehaviour
{
public void LoadNextScene()
{
Scene currentScene = SceneManager.GetActiveScene();
int nextIndex = currentScene.buildIndex + 1;
if (nextIndex < SceneManager.sceneCountInBuildSettings)
{
SceneManager.LoadScene(nextIndex);
}
else
{
SceneManager.LoadScene("MainMenu");
}
}
}这里的逻辑是:
当前是 Level01,buildIndex 是 1
下一关就是 2
所以加载 Level02案例 4:异步加载场景,做 Loading 进度条
c
using System.Collections;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
public class LoadingScene : MonoBehaviour
{
public Slider progressSlider;
public void LoadLevel(string sceneName)
{
StartCoroutine(LoadSceneRoutine(sceneName));
}
private IEnumerator LoadSceneRoutine(string sceneName)
{
AsyncOperation operation = SceneManager.LoadSceneAsync(sceneName);
while (!operation.isDone)
{
float progress = Mathf.Clamp01(operation.progress / 0.9f);
progressSlider.value = progress;
yield return null;
}
}
}注意:
operation.progress它表示加载进度。
Unity 的异步加载进度经常到 0.9 就接近完成,所以常见写法是:
float progress = Mathf.Clamp01(operation.progress / 0.9f);这样 UI 上可以显示成 0% 到 100%。
案例 5:Additive 叠加加载商店场景
假设你正在 Level01 里,想打开一个商店界面,但不想卸载当前关卡:
c
using UnityEngine;
using UnityEngine.SceneManagement;
public class ShopController : MonoBehaviour
{
public void OpenShop()
{
SceneManager.LoadScene("Shop", LoadSceneMode.Additive);
}
public void CloseShop()
{
SceneManager.UnloadSceneAsync("Shop");
}
}普通加载是:
c
SceneManager.LoadScene("Shop");意思是:
卸载当前场景
加载 Shop叠加加载是:
c
SceneManager.LoadScene("Shop", LoadSceneMode.Additive);意思是:
c
Level01 还在
Shop 也加载进来
两个场景同时存在案例 6:背景音乐切场景不断
c
using UnityEngine;
public class AudioManager : MonoBehaviour
{
private static AudioManager instance;
private void Awake()
{
if (instance != null)
{
Destroy(gameObject);
return;
}
instance = this;
DontDestroyOnLoad(gameObject);
}
}这个案例非常重要。
如果你不加:
c
DontDestroyOnLoad(gameObject);那么从 MainMenu 切到 Level01 时,音乐对象会被销毁。
如果你只加 DontDestroyOnLoad,但不检查重复对象,那么你每次回到菜单可能又生成一个新的 AudioManager,最后音乐重叠播放。
所以要一起写:
c
有旧的,就销毁新的
没有旧的,就保留自己你现阶段最该掌握的 5 个
c
SceneManager.LoadScene("场景名");
SceneManager.LoadScene(场景序号);
SceneManager.GetActiveScene();
SceneManager.LoadSceneAsync("场景名");
DontDestroyOnLoad(gameObject);初学练习建议你做一个小项目:
c
MainMenu -> Level01 -> GameOver实现:
c
开始按钮:进入 Level01
死亡按钮:进入 GameOver
重试按钮:重新加载 Level01
返回按钮:回到 MainMenu
背景音乐:切场景不断这套做完,Unity 场景系统的常用 API 你就真的会用了。