3.

Unity シーン移動方法|SceneManager.LoadScene / 非同期ロード / Build Settings

編集
この記事の要点
  • Unity でシーンを移動する方法
  • 基本: SceneManager.LoadScene("シーン名")
  • 事前に Build Settings の Scenes In Build に対象シーンを追加(忘れがち!)
  • 非同期ロード: SceneManager.LoadSceneAsync(...) — 進捗バー付きロード画面用
  • 加算ロード: LoadSceneMode.Additive — 現在シーンに重ねて読み込み(マップ分割等)
  • シーン間でデータを引き継ぐなら DontDestroyOnLoad または ScriptableObject

基本: SceneManager.LoadScene

using UnityEngine;
using UnityEngine.SceneManagement;  // ★ 必須

public class SceneChanger : MonoBehaviour {
    // 衝突時に scene2 へ遷移
    void OnCollisionEnter(Collision collision) {
        if (collision.gameObject.name == "GoalObject") {
            SceneManager.LoadScene("scene2");
        }
    }

    // ボタンから呼ぶ場合
    public void GoToTitle() {
        SceneManager.LoadScene("TitleScene");
    }

    // インデックス指定でも可(Build Settings の順序)
    public void GoToFirstScene() {
        SceneManager.LoadScene(0);
    }
}

事前準備: Build Settings に追加

シーン名で読み込むためには、対象シーンを Build Settings に登録しておく必要があります:

  1. File → Build Settings (Ctrl + Shift + B)
  2. 「Scenes In Build」の欄に対象シーンファイル (.unity) をドラッグ&ドロップ
  3. もしくは「Add Open Scenes」ボタンで現在開いているシーンを追加
  4. 不要なシーンはチェックを外すかリストから削除
  5. 各シーンに付いているインデックス番号は LoadScene(int) 引数で使用

未登録のシーンを LoadScene すると以下のエラー:

Scene 'scene2' couldn't be loaded because it has not been added to the build settings
or the AssetBundle has not been loaded.

非同期ロード (LoadSceneAsync)

重いシーンを読み込む場合、同期 LoadScene だと画面がフリーズします。非同期ロードで進捗バーを表示:

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

public class LoadingScreen : MonoBehaviour {
    public Slider progressBar;
    public Text progressText;

    public void StartLoading(string sceneName) {
        StartCoroutine(LoadSceneCoroutine(sceneName));
    }

    IEnumerator LoadSceneCoroutine(string sceneName) {
        AsyncOperation op = SceneManager.LoadSceneAsync(sceneName);
        op.allowSceneActivation = false;  // 読み込み完了しても自動切替しない

        while (!op.isDone) {
            // progress は 0.0〜0.9 まで進む(0.9 で読み込み完了、残り 0.1 はアクティブ化)
            float progress = Mathf.Clamp01(op.progress / 0.9f);
            progressBar.value = progress;
            progressText.text = $"{(progress * 100):F0}%";

            // 完了したらユーザー操作で遷移
            if (op.progress >= 0.9f) {
                progressText.text = "Press any key to continue";
                if (Input.anyKey) {
                    op.allowSceneActivation = true;
                }
            }
            yield return null;
        }
    }
}

加算ロード (Additive)

現在のシーンに重ねて別シーンを読み込む。広大なマップを区画分けする・UI とゲームを別シーンで管理する場合に使用:

// メインシーンを残したまま UI シーンを追加読み込み
SceneManager.LoadScene("UIScene", LoadSceneMode.Additive);

// 不要になったら個別アンロード
SceneManager.UnloadSceneAsync("UIScene");

// 現在ロードされているシーン一覧
for (int i = 0; i < SceneManager.sceneCount; i++) {
    var scene = SceneManager.GetSceneAt(i);
    Debug.Log($"Scene {i}: {scene.name} (loaded: {scene.isLoaded})");
}

シーン間のデータ引き継ぎ

シーン移動時、デフォルトではすべての GameObject が破棄されます。スコアやプレイヤー状態を引き継ぐには:

方式1: DontDestroyOnLoad

public class GameManager : MonoBehaviour {
    public static GameManager Instance;
    public int score = 0;

    void Awake() {
        if (Instance == null) {
            Instance = this;
            DontDestroyOnLoad(gameObject);  // ★ シーン跨ぎで保持
        } else {
            Destroy(gameObject);  // 重複インスタンス防止
        }
    }
}

// 別シーンから参照
void Start() {
    Debug.Log(GameManager.Instance.score);  // 前シーンのスコアが残っている
}

方式2: ScriptableObject(推奨)

[CreateAssetMenu(fileName = "GameState", menuName = "Game/State")]
public class GameState : ScriptableObject {
    public int score;
    public string playerName;
    public int level;
}

// 各シーンの MonoBehaviour で参照
public class ScoreDisplay : MonoBehaviour {
    public GameState gameState;  // Inspector でアサイン
    void Update() {
        scoreText.text = gameState.score.ToString();
    }
}

方式3: PlayerPrefs (永続化)

// セッション跨ぎで保存したい場合
PlayerPrefs.SetInt("HighScore", 12345);
PlayerPrefs.SetString("PlayerName", "Hero");
PlayerPrefs.Save();

// 読み込み
int hi = PlayerPrefs.GetInt("HighScore", 0);  // デフォルト値 0

シーン読み込みイベント

void OnEnable() {
    SceneManager.sceneLoaded += OnSceneLoaded;
}

void OnDisable() {
    SceneManager.sceneLoaded -= OnSceneLoaded;
}

void OnSceneLoaded(Scene scene, LoadSceneMode mode) {
    Debug.Log($"Scene loaded: {scene.name}, mode: {mode}");
    // シーン固有の初期化処理
}

よくあるハマりどころ

  • Build Settings 登録忘れ: 最頻出。エラーメッセージを必ず読む
  • シーン名のスペル: 大文字小文字を含めて完全一致
  • 同期 LoadScene でフリーズ: 大きいシーンは LoadSceneAsync に切替
  • DontDestroyOnLoad で重複: シーン再ロード時に既存インスタンスを残しつつ新規も生成 → シングルトン判定必須
  • Build 時にシーンが含まれない: Build Settings のチェックボックスが外れている
編集
Post Share
子ページ

子ページはありません

同階層のページ
  1. スクリプトの作成と実行
  2. C#のクラス一覧
  3. シーンの移動方法
  4. オブジェクトの移動・回転
  5. キーボードの入力値を受け取る
  6. オブジェクトの取得とコンポーネントの取得
  7. 衝突時の処理
  8. Webページを開く
  9. コンポーネントの取得
  10. 処理を一定時間待つ
  11. コンソールへのログ出力方法
  12. 飛行機の加速と減速
  13. ジェットエンジンのエフェクトとオーディオ