
在製作遊戲當中,不論是切換大地圖,或是進行戰鬥畫面,都有可能會用到Scene的轉場。最近碰到的需求是:玩家在大地圖碰到怪物,會進入戰鬥場景,因此實作這樣的功能。
其中有幾點要考量的:
- 是否真的需要新增一個Scene?
- 轉場時如何帶入額外的參數使用?
是否真的需要新增一個Scene?
新增Scene的適合情境:
- 當遊戲需要分割不同遊戲階段或關卡時,例如主選單、大廳、商店、遊戲關卡等,每個都是獨立的Scene,方便管理和場景切換。
- 需要明確區分不同場景內容和資源,避免過度雜亂一個Scene時,也便於場景載入和卸載。
- 希望運用Unity的Scene管理功能來控制載入流程、場景轉換,以及場景特有的設定如光照、相機、UI等時,就應該使用Scene。
- 例如大型遊戲會用多個Scene來分割劇情和遊戲世界的各個部分
使用GameObject實作的適合情境:
- 當需要在場景中新增、操作具體的物件時,如角色、敵人、道具、環境物件等,都以GameObject為核心實體。
- 在同一個Scene內管理互動物件時,利用GameObject和各種Component組合以實現功能與效果。
- 動態生成和銷毀物件,如彈幕、特效、子彈池等,通常透過Instantiate與Destroy方法操作GameObject。
- 在場景中以邏輯單位管理可見元素,透過腳本賦予行為和事件反應
轉換場景時,如果裡面的物件很多,必定會出現需要玩家等待Loading的狀況,因此有時候利用GameObject來實作某些彈窗、面板,是一個體驗更好的選擇。
轉場時如何帶入額外的參數使用?
新增一隻Singleton的Script,姑且取名叫GameManager,讓他扮演中間人的角色,幫我們在多個場景間轉移資料,為什麼做得到呢?利用的特性如下:
- Singleton指的是單例模式,能夠確保程式期間只會存在單著物件。也就是存資料時找個物件A,拿資料時也只會跟物件A拿,保證不會蹦出個物件B
- 使用DontDestroyOnLoad函數,使這位物件人兄在遊戲期間都能活得好好的。一般來說在切場景時,當前場景內的物件會被砍光光,因此藉由呼叫這個函式,讓物件能繼續存活。
再來可以宣告一個Class,結構化的儲存想要傳遞的資訊,比如說玩家現在剩多少血啦、等等進戰鬥畫面要放哪隻怪物的圖片啦,諸如此類。後面的例子我們宣告他為BattleInitData。
GameManager.cs參考
using UnityEngine;
using UnityEngine.SceneManagement;
public class GameManager : MonoBehaviour
{
public static GameManager Instance { get; private set; }
[Header("場景資訊")]
public string mainSceneName = "MainVillage";
[Header("戰鬥相關資料")]
private BattleInitData currentBattleData;
private BattleResult battleResult;
private Vector3 playerReturnPosition;
private void Awake()
{
// Singleton 實作
if (Instance != null && Instance != this)
{
Destroy(gameObject);
return;
}
Instance = this;
DontDestroyOnLoad(gameObject);
}
public void SetBattleData(BattleInitData battleData)
{
currentBattleData = battleData;
}
public void SetBattleResult(BattleResult result)
{
battleResult = result;
}
public void SetReturnPosition(Vector3 position)
{
playerReturnPosition = position;
}
public BattleInitData GetBattleData()
{
return currentBattleData;
}
public BattleResult GetBattleResult()
{
return battleResult;
}
public void ReturnToMainScene()
{
SceneManager.LoadScene(mainSceneName);
}
}
BattleInitData參考
using UnityEngine;
[System.Serializable]
public class BattleInitData
{
[Header("敵人資訊")]
public EnemyData enemyData;
[Header("玩家資訊")]
public int playerCurrentHP;
public int playerMaxHP;
[Header("戰鬥獎勵")]
public int baseExperienceReward; // 基礎經驗值獎勵
public BattleInitData(EnemyData enemy, int currentHP, int maxHP, int expReward)
{
enemyData = enemy;
playerCurrentHP = currentHP;
playerMaxHP = maxHP;
baseExperienceReward = expReward;
}
}
觸發切換場景的方式
實作以下程式碼,放在你覺得適合的地方。我是放在怪物身上腳本的OnTriggerEnter2D函式內,讓玩家碰觸到怪物時觸發轉場。
using UnityEngine.SceneManagement;
SceneName = "場景名稱"
SceneManager.LoadScene(SceneName);
還有什麼要設定的?
從上述的例子裡,至少有兩個場景會使用到,這兩個場景都要加到 Unity 的「建置設定(Build Settings)」內,不然程式執行SceneManager.LoadScene()時會報錯。
我是使用Unity6.0,設定方式是到File->Build Profile,找到視窗內的Scene List,直接把開發介面中的Project介面裡的場景檔案托拉進去Scene List內即可,也可以按Add Open Scene將當前場景加入。


