この記事でわかること
- Unityのシーン管理、シーン(Scene)について
- SceneManagerを使ったシーンの切り替え方法
- シーンの非同期ロード(ロード画面の作成)
- DontDestroyOnLoadを使ったデータの引き継ぎ
- シーン管理の最適化テクニック
Unityのシーン管理とは?
Unityでシーンを管理するには「SceneManager」を使用します。
このクラスを使うと以下のような操作が可能です。
- シーンを読み込む
- シーンを追加で読み込む(Additive)
- 現在のシーン情報を取得する
シーン(Scene)とは?
シーン(Scene)は、ゲームの各シーン(タイトル画面・ステージ・結果画面)を管理する単位です。
・ゲーム全体を1つのシーンで作るのではなく、複数のシーンに分割すると管理しやすい!
・シーンごとにオブジェクトを整理し、ロード・切り替えがスムーズに!

Unityのシーン管理(SceneManager)
シーン(Scene)の作成、保存
① Projectから追加
- [Project] → [Scenesフォルダ] → [右クリック] → [Create] → [Scene] → [Scene] を選択
- Scenesフォルダ内にシーン(Scene)が追加される
- シーン(Scene)名を入力して決定

シーン(Scene)を追加する方法
シーンを追加しないと、SceneManager.LoadScene()で読み込まないので注意が必要です。
- File→Build Settings開く(Unity6だとBuild Profiles)
- Scenes In Buildに最新シーンをドラッグ&ドロップか「Add Open Scemes」で追加(Unity6だとScene List)
- シーンの順番を調整し、Build & Run実行可能にする

シーン管理(SceneManager)をスクリプトで制御
シーン管理(SceneManager)の準備
最初にSceneを2つ用意してください。(今回はSampleScene、New Scene)
次にヒエラルキーで右クリックをして空のGameObjectとButtonを1つずつ用意します。
・「右クリック」→「Create Empty」
・「右クリック」→「UI」→「Button – TextMeshPro」
次にスクリプトを作成して先ほどのCreate Emptyにアタッチしてください。

現在のシーンの取得
シーンを跨ぐような変数を用いる場合にシーンによって挙動を変えたいことがあります。そのような時に「SceneManager.GetActiveScene()」を使用すると現在のシーンが取得できます。
using UnityEngine;
using UnityEngine.SceneManagement;
public class SceneManagerScript : MonoBehaviour
{
[SerializeField] private Scene scene;
void Start()
{
scene = SceneManager.GetActiveScene();
Debug.Log("現在のシーン名: " + scene.name);
}
}
実行してみると、現在のシーン名が取得できますね。
シーン(Scene)の切り替え
SceneManager.LoadScene()でシーン切り替え(同期)
シーン切り替えといえばまずは同期のシーン切り替えです。「LoadScene(“シーン名”)」を使用すれば簡単にシーンが切り替わります。
※ボタンはインスペクターでアタッチしておいてください。
using UnityEngine;
using UnityEngine.SceneManagement;
public class SceneChanger : MonoBehaviour
{
public void ChangeScene()
{
SceneManager.LoadScene("New Scene"); // シーン名で指定
}
}
実行してみると、切り替わりましたね。ヒエラルキーが「New Scene」に変わりました。
LoadSceneAsync()でシーン切り替え(非同期)
シーンのロード時にカクつきを防ぐため、シーン切り替え時には非同期で切り替えをする場合があります。そのような時は「LoadSceneAsync()」を使って非同期でシーンを読み込むのがベストです。
- 進行状況(operation.progress)をスライダーで表示!
- ロード画面を見せることで、ユーザー体験を向上!
using System.Collections;
using TMPro;
using Unity.VisualScripting;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
public class SceneManagerScript : MonoBehaviour
{
[SerializeField] private string sceneName;
[SerializeField] private Button changeButton;
public GameObject loadingScreen; // ローディング画面
public Slider progressBar; // プログレスバー
public TextMeshProUGUI progressText; // 進捗率(%表示用)
// 擬似的に遅延させるための値
float displayProgress = 0f;
void Start()
{
sceneName = "New Scene";
changeButton.onClick.AddListener(LoadScene); ;
}
// シーンをロードするメソッド(UIボタンから呼び出す)
public void LoadScene()
{
StartCoroutine(LoadSceneAsync(sceneName));
}
// 非同期ロード
IEnumerator LoadSceneAsync(string sceneName)
{
// ローディング画面を表示
loadingScreen.SetActive(true);
// シーンを非同期でロード開始(allowSceneActivation=false にして最後に切り替え)
AsyncOperation operation = SceneManager.LoadSceneAsync(sceneName);
operation.allowSceneActivation = false;
while (!operation.isDone)
{
// 実際の進捗 (0~0.9 → 0~1に補正)
float targetProgress = Mathf.Clamp01(operation.progress / 0.9f);
// 実際の値に近づけていく (時間をかけて滑らかに)
displayProgress = Mathf.MoveTowards(displayProgress, targetProgress, Time.deltaTime * 0.5f);
progressBar.value = displayProgress;
progressText.text = (displayProgress * 100f).ToString("F0") + "%";
if (displayProgress >= 1f)
{
yield return new WaitForSeconds(0.5f); // デモ用に待機
operation.allowSceneActivation = true;
}
yield return null;
}
}
}
実行してみると、時間差で移行されましたね。
※今回はデモ用なので実動作はWhileの中身を書き換えてください。
シーン間でデータを保持する方法
DontDestroyOnLoad()を使う
シーンを切り替え時にデータを保持する方法として「DontDestroyOnLoad()」を使います。また、シーン間でデータを保持したい場合はstaticを使いましょう。
using UnityEngine;
public class GameManager : MonoBehaviour
{
public static GameManager instance;
public int playerScore = 0;
void Awake()
{
if (instance == null)
{
instance = this;
DontDestroyOnLoad(gameObject);
}
else
{
Destroy(gameObject);
}
}
}
テキストにデータを保存する
PlayerPrefsやJSONを使うと、シーンが切り替わってもデータを半永続的に保存できる。
※ PlayerPrefsはUnityから非推奨とされています。
シーン管理の最適化
メモリ最適化(不要なオブジェクトの削除)
シーン移行後に不要なオブジェクトを削除することで、メモリ使用量を削減することが可能です。
void OnSceneLoaded(Scene scene, LoadSceneMode mode)
{
Resources.UnloadUnusedAssets();
}
よくあるエラーと解決策
SceneManager.LoadScene()が動作しない
・解決策:Build Settingsにシーンを追加する!
・解決策:シーン名スペルミスをチェック!
シーンが切り替わると変数がリセットされる
・解決策:DontDestroyOnLoad()でデータを保存!
・解決策:PlayerPrefsでデータを保存!
まとめ
・SceneManager.LoadScene()を使えば簡単にシーン移行できる!
・非同期ロード( LoadSceneAsync())を使えるとロード画面ができる!
・DontDestroyOnLoad()を使えばデータを保持可能!
・UIを別シーンに一時的に、シーンロードを高速化!