Unity 6 マルチシーン開発テンプレートプロジェクト

前書き

このドキュメントでは、Unity 6が提供するマルチシーン機能を活用し、大規模プロジェクトやチーム開発における効率的なワークフローを確立するためのテンプレート構成を紹介します。シーンを機能別に分割して管理することで、作業の並行化や役割分担が容易になり、品質向上と開発スピードの両立を実現します。

1. プロジェクト構成例

Assets/
├── Scenes/
│   ├── MainScene.unity               # 本番用の統合シーン(アクティブ)
│   ├── UIOverlayScene.unity          # UI専用シーン(Additive)
│   ├── GlobalManagerScene.unity      # マネージャー系シーン(Additive)
│   ├── Scene_Template_Work.unity     # 作業用ベースシーン(複製して使用)
│   ├── Scene_Konishi_EnemyTest.unity # 小西さん作業用シーン
│   └── Scene_Inoue_UITest.unity      # UI開発者用シーン
├── Prefabs/
│   ├── Managers/                     # 各種マネージャーPrefab
│   ├── UI/                           # UI関連Prefab
│   └── Characters/                   # キャラクターPrefab
├── Scripts/
│   ├── Bootstrap/                    # 起動・シーン読み込み用スクリプト
│   ├── Managers/                     # ゲーム全体管理用スクリプト
│   └── Game/                         # ゲーム本体ロジック
└── Resources/                        # ランタイムロード用リソース

解説

  • Scenes/:複数のシーンを分割して管理することで、UIやグローバルマネージャーなどを独立して開発・テストできる。
  • Prefabs/:共通で使うオブジェクトはPrefab化して再利用性を高め、アセットの重複を防止。
  • Scripts/:機能ごとにフォルダを分けることで見通しを良くし、チームメンバー間で役割を分担しやすくする。
  • Resources/:動的にロードが必要なアセット(例:外部データ、ユーザー生成コンテンツ等)を格納。

2. BootstrapLoader サンプルコード

using UnityEngine;
using UnityEngine.SceneManagement;
using System.Collections;

public class BootstrapLoader : MonoBehaviour
{
    [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.AfterSceneLoad)]
    static void OnStart()
    {
        var go = new GameObject("Bootstrap");
        go.AddComponent<BootstrapLoader>();
        DontDestroyOnLoad(go);
    }

    private void Start()
    {
        StartCoroutine(LoadScenes());
    }

    private IEnumerator LoadScenes()
    {
        // GlobalManagerScene を読み込む
        yield return SceneManager.LoadSceneAsync("GlobalManagerScene", LoadSceneMode.Additive);

        // UIOverlayScene を読み込む
        yield return SceneManager.LoadSceneAsync("UIOverlayScene", LoadSceneMode.Additive);

        // MainScene を読み込み、アクティブシーンに設定
        yield return SceneManager.LoadSceneAsync("MainScene", LoadSceneMode.Additive);
        SceneManager.SetActiveScene(SceneManager.GetSceneByName("MainScene"));
    }
}

解説

  • RuntimeInitializeOnLoadMethod:アプリ起動後、自動的にメソッドが呼ばれ、Bootstrap用のGameObjectを生成。
  • DontDestroyOnLoad:シーン切り替え時にオブジェクトが破棄されないように設定。
  • LoadSceneAsync + LoadSceneMode.Additive:必要なサブシーンを順次読み込むことで、開発・テスト時に個別機能を組み合わせやすくする。
  • SetActiveScene:最後にメインシーンをアクティブに指定し、入力やライトの対象を明確化。

3. 活用方法

  1. 作業用シーンの準備
    Scene_Template_Work.unity を複製し、Scene_<名前>_<目的>.unity にリネーム。
    — 目的ごとに専用シーンを用意し、コンフリクトを防ぎ、チームメンバーが並行作業しやすくする。
  2. Prefab 化の徹底
    再利用可能なオブジェクトはすぐ Prefab 化し、Assets/Prefabs/ 配下へ。
    — アセット更新時の手戻りを減らし、一元管理でバージョン管理も容易に。
  3. 統合前テスト
    Play モードで BootstrapLoader を通じた全体構成を確認。
    — 実際のリリース構成に近い状態でテストを行い、シーン間連携の問題を早期検出。
  4. ビルド・リリース準備
    MainScene.unity に最終的な Prefab やオブジェクトを配置し、本番ビルドを実行。
    — 本番用の統合シーンだけに必要要素をまとめることで、ビルドサイズを最適化。

4. 配布・共有

  • .unitypackage や ZIP アーカイブでテンプレートをまとめて提供可能。
  • 以下の要素を追加検討するとより実用的:
    • UI 管理フレームワーク(例:UIToolkit、UniRX連携など)
    • AudioManager/BGM・SE 制御サンプル
    • プレイヤー操作入力サンプル(新Input System対応)
    • シーン間データ受け渡し(ScriptableObject、Addressablesなど)

必要な要素やカスタマイズがあればご相談ください。

5. マルチシーン利用時の注意点

  • シーンのロード順と依存関係
    Additive読み込みの順序によって依存するオブジェクトが未初期化になることがあるため、GlobalManager→UIOverlay→Mainのように依存関係を明確にしておく。
  • アクティブシーンの設定
    Additiveだけでは入力やライトのターゲットが意図しないシーンに残る可能性があるため、必ず最後に SceneManager.SetActiveScene を呼び出してアクティブシーンを切り替える。
  • 同名オブジェクトの衝突
    複数シーンに同じ名前のGameObjectやタグがあると、Find 系APIが誤ったオブジェクトを返す恐れがある。ルートオブジェクト名やタグにプレフィックスを付けて衝突を避ける。
  • シングルトン/DontDestroyOnLoadの重複
    各シーンで同じシングルトンを生成するとインスタンスが重複しやすい。初期化前に既存インスタンスの有無をチェックし、不要なインスタンスを破棄するロジックを実装。
  • アンロード時のリソース解放
    SceneManager.UnloadSceneAsync でシーンをアンロードする際、シーン内の参照が残っているとGCされずメモリリークに繋がる。イベントやコルーチン、静的参照の解除を忘れない。
  • アセット共通化と依存管理
    複数シーンで共有するアセットは Addressables や Addressable Asset Groups を活用し、シーン切り替え時のロード/アンロードを管理する。
  • Gitコンフリクト対策
    シーンファイルやPrefabはテキストベースのマージが難しいため、複数人での同時編集を避ける。作業用シーンは都度ブランチを切り、マージタイミングを明確にする。