Unity 場景API詳解
本文提供全圖文流程,中文翻譯。
Chinar 堅持将簡單的生活方式,帶給世人!
(擁有更好的閱讀體驗 —— 高分辨率使用者請根據需求調整網頁縮放比例)
Chinar —— 心分享、心創新!
助力快速了解 Unity 場景管理的 API 諸多用法
給新手節省寶貴的時間,避免采坑!
Chinar 教程效果:

1
SceneManager —— 場景管理
我們在遊戲開發中,經常用到關卡切換、場景切換、加載場景等諸多功能性操作
Unity 為我們提供了場景管理類,可以很友善的對場景進行各類操作
下邊我們就來逐一的看一下,API中的函數具體用法
另附——
官方API連結 其他
2
API —— API(建立/擷取/加載)
直接給大家貼上中文注釋,便于初學者學習
其他易出錯的函數, Chinar 也用了簡單例子做了說明,避免初學者踩坑!
提示:
其中 0 号場景為: SampleScene
其中 1 号場景為: Chinar
using System.Collections;
using UnityEngine;
using UnityEngine.SceneManagement;
/// <summary>
/// 場景管理測試類
/// </summary>
public class ChinarSceneManager1 : MonoBehaviour
{
/// <summary>
/// 初始化函數
/// </summary>
void Start()
{
SceneManager.CreateScene("Chinar"); //使用給定名稱在運作時建立一個空的新場景
SceneManager.GetActiveScene(); //擷取目前活動的場景
SceneManager.GetSceneAt(0); //在SceneManager的已加載場景清單中擷取索引處的場景
SceneManager.GetSceneByBuildIndex(0); //從建構Build Setting中索引擷取Scene結構
SceneManager.GetSceneByName("Chinar"); //搜尋給定名稱的場景
SceneManager.GetSceneByPath("Assets/Scenes/SampleScene.unity"); //搜尋給定路徑的場景
SceneManager.LoadScene(1); //根據“Build Setting”中索引加載場景
SceneManager.LoadScene("Chinar"); //根據“Build Setting”中名稱加載場景
SceneManager.LoadScene(1, LoadSceneMode.Additive); //加載場景,加載方式:保留目前場景,附加指定場景
SceneManager.LoadScene("Chinar", LoadSceneMode.Single); //加載場景,加載方式:關閉所有目前加載的場景并加載場景
SceneManager.LoadSceneAsync(1); //根據下标,在背景異步加載場景
SceneManager.LoadSceneAsync("Chinar"); //根據名稱,在背景異步加載場景
SceneManager.LoadSceneAsync(1, LoadSceneMode.Additive); //異步加載,方式:附加
SceneManager.LoadSceneAsync(1); //異步加載,方式:單一
SceneManager.UnloadSceneAsync("Chinar"); //銷毀與給定場景關聯的所有GameObject,并從SceneManager中移除場景。
}
}
3
API (Merge) —— 常用API(合并/移動對象/設定活動)
有時我們需要将場景合并
或者将目前場景的遊戲對象,移動到其他場景中 / 設定活躍場景
進行這三類操作,都需要先将目标場景加載後,才可保證函數正确執行
這裡為了便于初學者了解,我用了協成加載的方式,來做說明
using System.Collections;
using UnityEngine;
using UnityEngine.SceneManagement;
/// <summary>
/// 場景管理測試類
/// </summary>
public class ChinarSceneManager1 : MonoBehaviour
{
/// <summary>
/// 初始化函數
/// </summary>
void Start()
{
StartCoroutine(MergeMethodEnumerator()); //合并場景
StartCoroutine(MoveGameObjectToSceneEnumerator()); //移動遊戲對象到目标場景
StartCoroutine(SetActiveSceneEnumerator()); //設定場景為活動場景
}
/// <summary>
/// 合并場景
/// 必須要保證:要合并的場景被加載後,才可以正确合并
/// 如果物體名稱相同,并不會合并,互相獨立
/// </summary>
IEnumerator MergeMethodEnumerator()
{
yield return SceneManager.LoadSceneAsync(1, LoadSceneMode.Additive); //等待場景加載完畢後,再向下執行
SceneManager.MergeScenes(SceneManager.GetSceneByBuildIndex(1), SceneManager.GetActiveScene()); //源場景 1,目标場景:目前 —— 将源場景合并到目标場景中
}
/// <summary>
/// 移動遊戲對象到新場景
/// 必須要保證:目标場景被加載後,遊戲對象才能被正确移動到目标場景中
/// 如果物體名稱相同,并不會合并,互相獨立
/// </summary>
IEnumerator MoveGameObjectToSceneEnumerator()
{
yield return SceneManager.LoadSceneAsync(1, LoadSceneMode.Additive); //等待場景加載完畢後,再向下執行
SceneManager.MoveGameObjectToScene(GameObject.Find("Cube"), SceneManager.GetSceneByName("Chinar")); //将目前場景中的 Cube,移動到目标場景中
SceneManager.UnloadSceneAsync(SceneManager.GetActiveScene()); //解除安裝掉目前場景
//如果要加載單個場景,請確定在要移動到新場景的GameObject上使用DontDestroyOnLoad,否則Unity會在加載新場景時删除它。
}
/// <summary>
/// 設定場景為活動場景
/// 必須要保證:目标場景被加載後,才可以正确設定活動狀态
/// </summary>
IEnumerator SetActiveSceneEnumerator()
{
yield return SceneManager.LoadSceneAsync(1, LoadSceneMode.Additive); //等待場景加載完畢後,再向下執行
SceneManager.SetActiveScene(SceneManager.GetSceneAt(1)); //設定場景為活動場景
//print(SceneManager.GetSceneAt(1).IsValid());
}
}
4
Scene (Events) —— 場景事件
有時我們需要場景記載/解除安裝/變更時,進行一系列操作
這時我們需要用事件來完成通知
using System.Collections;
using UnityEngine;
using UnityEngine.SceneManagement;
/// <summary>
/// 場景管理測試類
/// </summary>
public class ChinarSceneManager1 : MonoBehaviour
{
/// <summary>
/// 初始化函數
/// </summary>
void Start()
{
SceneManager.activeSceneChanged += SceneManager_activeSceneChanged; //訂閱此事件可在活動場景發生更改時收到通知。
StartCoroutine(SetActiveSceneEnumerator()); //活動場景切換時,會收到通知,列印輸出"活動場景變更了"
SceneManager.sceneLoaded += SceneManager_sceneLoaded; //委托 —— 加載場景時收到通知
SceneManager.LoadSceneAsync(1); //異步加載,加載方式:單一
SceneManager.sceneUnloaded += SceneManager_sceneUnloaded; //委托 —— 解除安裝Scene時收到通知
}
/// <summary>
/// 設定場景為活動場景
/// 必須要保證:目标場景被加載後,才可以正确設定活動狀态
/// </summary>
IEnumerator SetActiveSceneEnumerator()
{
yield return SceneManager.LoadSceneAsync(1, LoadSceneMode.Additive); //等待場景加載完畢後,再向下執行
SceneManager.SetActiveScene(SceneManager.GetSceneAt(1)); //設定場景為活動場景
}
/// <summary>
/// 活動場景變動時被調用
/// </summary>
private void SceneManager_activeSceneChanged(Scene arg0, Scene arg1)
{
print("活動場景變更了");
}
/// <summary>
/// 場景被加載後,被調用
/// </summary>
private void SceneManager_sceneLoaded(Scene arg0, LoadSceneMode arg1)
{
print("場景被加載了");
}
/// <summary>
/// 場景被解除安裝時,被調用
/// </summary>
private void SceneManager_sceneUnloaded(Scene arg0)
{
print("場景被解除安裝了");
}
}
5
Scene —— 場景自身的一些屬性
Scene 類自身具備一些屬性和字段,便于我們對場景的狀态進行了解/操作
using System.Collections;
using UnityEngine;
using UnityEngine.SceneManagement;
/// <summary>
/// 場景管理測試類
/// </summary>
public class ChinarSceneManager1 : MonoBehaviour
{
/// <summary>
/// 初始化函數
/// </summary>
void Start()
{
print(SceneManager.GetActiveScene().buildIndex); //傳回“Build Setting”中場景的索引。如果場景是通過AssetBundle加載的,則始終傳回-1。
print(SceneManager.GetActiveScene().isDirty); //如果場景被修改,則傳回true。
print(SceneManager.GetActiveScene().isLoaded); //如果加載場景,則傳回true。
print(SceneManager.GetActiveScene().name); //傳回場景的名稱。
print(SceneManager.GetActiveScene().path); //傳回場景的相對路徑。喜歡:“Assets/Scenes/SampleScene.unity”。
print(SceneManager.GetActiveScene().rootCount); //傳回場景的遊戲對象個數
print(SceneManager.GetActiveScene().GetHashCode()); //傳回場景的哈希值
print(SceneManager.GetActiveScene().GetRootGameObjects()); //傳回場景中所有遊戲對象,是一個GameObject[] 數組
foreach (var a in SceneManager.GetActiveScene().GetRootGameObjects())
{
print(a.name);
}
StartCoroutine(SetActiveSceneEnumerator()); //設定場景為活動場景
print(SceneManager.GetSceneAt(1).IsValid()); //判斷場景是否有效,如果場景未被加載/或是不存在,則場景可能無效
}
/// <summary>
/// 設定場景為活動場景
/// 必須要保證:目标場景被加載後,才可以正确設定活動狀态
/// </summary>
IEnumerator SetActiveSceneEnumerator()
{
yield return SceneManager.LoadSceneAsync(1, LoadSceneMode.Additive); //等待場景加載完畢後,再向下執行
SceneManager.SetActiveScene(SceneManager.GetSceneAt(1)); //設定場景為活動場景
}
}
May Be —— 搞開發,總有一天要做的事!
擁有自己的伺服器,無需再找攻略! Chinar 提供一站式教程,閉眼式建立! 為新手節省寶貴時間,避免采坑! |
END
本部落格為非營利性個人原創,除部分有明确署名的作品外,所刊登的所有作品的著作權均為本人所擁有,本人保留所有法定權利。違者必究
對于需要複制、轉載、連結和傳播部落格文章或内容的,請及時和本部落客進行聯系,留言,Email: [email protected]
對于經本部落客明确授權和許可使用文章及内容的,使用時請注明文章或内容出處并注明網址