Unity Term Book
コアとアーキテクチャ

Scene

Scene は GameObject・ライト・カメラを収める空間です。各 .unity ファイルがレベルやメニューといったゲーム状態を表し、SceneManager で切り替えます。LoadSceneAsync、Additive Loading、DontDestroyOnLoad の基礎もここで学べます。

想像してみてください...

Scene はドラマの 1 エピソードのようです。各話には独自のセット・登場人物・物語があります。次のエピソードへカット(Scene 読み込み)すると古いセットは消えます。全話を生き抜くキャラクターには DontDestroyOnLoad() ——レベル間で消えない主人公のように使います。

概念の詳細

典型的なゲームには多くの Scene があります: MainMenu、Level_01、Level_02、GameOver、Loading… 分割することで メモリを抑え、必要なものだけ読み込めます。

Scene の切り替えには SceneManager クラスを使います。LoadScene() は同期 (ブロッキング——ゲームが一時停止)、一方 LoadSceneAsync() はバックグラウンド読み込みなので Loading Screen を表示できます。

Additive Loading:複数の Scene を重ねて同時に読み込みます。 ワールドストリーミングや、UI Scene とゲームプレイ Scene の分離によく使います。

Scene 読み込みを越えて生き残る GameObject には DontDestroyOnLoad(gameObject) を使います。 Scene 再読み込み時の重複生成を防ぐため、必ず Singleton と組み合わせてください。

Scene フロー

🎬

MainMenu

index: 0

Loading

index: 1

🎮

Level_01

index: 2

💀

GameOver

index: 3

Single Mode

新しい Scene を読み込む → 古い Scene を破棄

Additive Mode

追加読み込み → 古い Scene を保持

ハンズオン手順

1

新しい Scene を作成

メニュー File → New Scene で Scene を作ります。

2

Build Settings に追加

File → Build Settings → .unity ファイルをリストへドラッグ。LoadScene(index) で使う番号がインデックスです。

3

スクリプトから Scene を切り替える

using UnityEngine.SceneManagement; を追加し、SceneManager.LoadScene() を呼びます。

4

Async で Loading Screen

Coroutine + LoadSceneAsync() を使い、AsyncOperation.progress(0.0 → 0.9)でプログレスバーを更新します。

インタラクティブシミュレーター

Load Scene をクリックして Loading Screen 付き遷移をシミュレート。GameManager が毎 Scene を生き残る様子も確認できます。

Build Settings

🔒 GameManager

DontDestroyOnLoad

Active Scene: MainMenu ·  Build Index: 0

コード例

基本
using UnityEngine;
using UnityEngine.SceneManagement;

public class SceneBasics : MonoBehaviour
{
  void Awake()
  {
      // Keep this object across every Scene (Singleton GameManager)
      DontDestroyOnLoad(gameObject);
  }

  public void LoadLevel1()
      => SceneManager.LoadScene("Level_01");      // by name

  public void RestartCurrentScene()
  {
      int idx = SceneManager.GetActiveScene().buildIndex;
      SceneManager.LoadScene(idx);                   // by index
  }

  public void LoadNextScene()
  {
      int next = SceneManager.GetActiveScene().buildIndex + 1;
      SceneManager.LoadScene(next);
  }
}

コード例

上級
using System.Collections;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

public class SceneLoader : MonoBehaviour
{
  public static SceneLoader Instance { get; private set; }
  [SerializeField] private Slider progressBar;

  void Awake()
  {
      // Singleton: only one instance may exist
      if (Instance != null) { Destroy(gameObject); return; }
      Instance = this;
      DontDestroyOnLoad(gameObject);
  }

  public void LoadScene(string sceneName)
      => StartCoroutine(LoadAsync(sceneName));

  private IEnumerator LoadAsync(string sceneName)
  {
      AsyncOperation op = SceneManager.LoadSceneAsync(sceneName);
      op.allowSceneActivation = false;

      while (op.progress < 0.9f)
      {
          float progress = Mathf.Clamp01(op.progress / 0.9f);
          if (progressBar) progressBar.value = progress;
          yield return null;
      }

      if (progressBar) progressBar.value = 1f;
      yield return new WaitForSeconds(0.5f);
      op.allowSceneActivation = true;
  }
}

📌 要点

  • LoadScene する前に Scene を Build Settings に入れる
  • DontDestroyOnLoad で遷移を越えてオブジェクトを残す
  • Async + Coroutine で Loading Screen を作る
  • ワールドストリーミングや UI 分離には Additive モード

⚠️ よくあるミス

  • ❌ Build Settings への追加を忘れる

    "Scene not found in Build Settings" エラー

    ✅ File → Build Settings → Add Open Scenes

  • ❌ Singleton ガードなしの DontDestroyOnLoad

    Scene 再読み込みで GameManager が二重化

    ✅ if (Instance != null) Destroy(this);