「スタートボタンを押したらステージへ」「ゲームオーバーになったらリザルトへ」——ゲームの流れは、シーンからシーンへの移動でできています。そしてこの移動、実装しようとすると「シーンが見つからないエラーが出る」「ロード中に画面が固まる」といった壁に当たりがちです。
Unityではシーン間の移動を SceneManager クラスで管理します。この記事では基本のロード方法から、フリーズを防 いでロード画面を出すための非同期ロードまで、シーン遷移の必須知識を解説します。
この記事でわかること
- シーンをビルド設定に登録する理由と手順
LoadScene()によるシーン名/ビルドインデックスでのロードLoadSceneAsync()とロード画面(プログレスバー)の実装- 「progressが0.9で止まる」仕組みの正体
動作確認環境: Unity 6 (6000.x) / Input System
シーンをビルド設定に追加する
スクリプトからシーンをロードする前に、まず対象となるすべてのシーンをビルド設定に登録しておく必要があります。これを忘れると、エディタ上では動作しても、実際にゲームをビルドした際にシーンが見つからずエラーになってしまいます。
File > Build Profilesを選択してビルドの設定ウィンドウを開きます。Scene Listというリストが表示されます。- プロジェクトウィンドウから、ゲームで使用するすべてのシーンファイル(
.unity)をこのリストにドラッグ&ドロップします。
リストに追加されたシーンには、0, 1, 2... というビルドインデックスが割り振られます。このインデックス番号、またはシーンファイル名(拡張子なし)を使って、スクリプトからシーンをロードすることができます。

ポイント: 一般的に、ビルドインデックス0はゲームの起動時に最初に読み込まれるシーン(タイトル画面やスプラッシュスクリーンなど)に設定します。
補足: Unity 2022 以前では、このウィンドウは
File > Build Settings...、リストの名前はScenes In Buildです。古い解説を読むときは読み替えてください。登録が必要という仕組み自体は同じです。リストを並べ替えると番号も変わるので、スクリプトからはシーン名で呼ぶほうが安全です。
基本的なシーンロード: LoadScene()
シーンをロードする最も簡単な方法は、SceneManager.LoadScene()メソッドを使うことです。このメソッドを使うには、スクリプトの先頭にusing UnityEngine.SceneManagement;を追加するのを忘れないでください。
LoadScene()は同期的に動作します。このメソッドを呼ぶと、次のフレームで新しいシーンの読み込みが始まり、終わるまで画面が止まります(呼んだ直後の行は、まだ古いシーンのまま実行されます)。ロードに時間がかかる重いシーンの場合、ゲームが一瞬フリーズしたように見えることがあります。

シーン名でロードする
using UnityEngine;
using UnityEngine.SceneManagement; // これが必要!
public class TitleScreen : MonoBehaviour
{
public void OnStartButtonClick()
{
// ビルド設定に追加したシーンのファイル名を文字列で指定
SceneManager.LoadScene("GameStage1");
}
}
ビルドインデックスでロードする
using UnityEngine;
using UnityEngine.SceneManagement;
public class GameController : MonoBehaviour
{
public void GoToTitle()
{
// ビルドインデックス0番のシーン(タイトル画面)をロード
SceneManager.LoadScene(0);
}
}
非同期ロードとロード画面の実装: LoadSceneAsync()
ゲームがフリーズするのを避け、ロード中であることをプレイヤーに伝える「ロード画面」を実装するには、非同期でのシーンロードが必要です。SceneManager.LoadSceneAsync()メソッドは、シーンデータの読み込みを主にバックグラウンドで行い、ロード中も画面の更新や演出を続けられます。
補足: 「完全にゲームを止めない」わけではない点は知っておきましょう。最後の アクティベーション(新しいシーンのオブジェクト生成や
Awakeの実行)はメインスレッドで走るため、切り替わりの瞬間のカクつきは残り得ます。「非同期=魔法のようにゼロコスト」ではなく、「重い待ち時間の間もロード画面を動かせる仕組み」と捉えるのが正確です。
LoadSceneAsync()は、ロード処理の状況を管理するAsyncOperationオブジェクトを返します。このオブジェクトのプロパティを調べることで、ロードの進捗状況を取得したり、ロードが完了したかを検知したりできます。
以下は、簡単なロード画面の実装例です。
using System.Collections;
using TMPro; // TextMeshPro用
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI; // Sliderを操作するために必要
public class LoadingScreen : MonoBehaviour
{
public Slider progressBar; // ロードの進捗を表示するUIスライダー
public TMP_Text progressText; // 進捗をパーセント表示するUIテキスト
private bool isLoading; // 連打による多重ロードを防ぐ
public void LoadScene(string sceneName)
{
if (isLoading) return; // ボタン連打でも2回目以降は無視
isLoading = true;
// コルーチンを開始して非同期ロードを行う
StartCoroutine(LoadAsynchronously(sceneName));
}
IEnumerator LoadAsynchronously(string sceneName)
{
// LoadSceneAsyncメソッドでシーンを非同期でロード開始
AsyncOperation operation = SceneManager.LoadSceneAsync(sceneName);
// isDoneがtrueになるまでループ
while (!operation.isDone)
{
// progressは読み込みで0.9まで進み、残りの0.1は切り替え(0.9で読み込み完了)
float progress = Mathf.Clamp01(operation.progress / 0.9f);
// プログレスバーとテキストを更新
progressBar.value = progress;
progressText.text = (progress * 100f).ToString("F0") + "%";
// 1フレーム待つ
yield return null;
}
}
}
operation.progressは、ロードが90%完了した時点で0.9という値を返します。実際のシーンのアクティベーション(表示の切り替え)は最後の10%で行われるため、100%表示にするにはprogress / 0.9fのように計算するのが一般的です。

ロード完了を待ってから切り替える: allowSceneActivation
「progressが0.9で止まる」現象を実際に目にするのは、 allowSceneActivation を使ったときです。これをfalseにすると、データのロードが終わってもシーンは自動で切り替わらず、progressは0.9のまま待機します(isDoneもtrueになりません)。「ロード完了 → PRESS ANY KEYで開始」という定番の演出は、この仕組みで作ります。
IEnumerator LoadWhenReady(string sceneName)
{
AsyncOperation operation = SceneManager.LoadSceneAsync(sceneName);
operation.allowSceneActivation = false; // 自動で切り替えない
// データのロードが終わると、progressは0.9で止まる
while (operation.progress < 0.9f)
{
yield return null;
}
// 「準備完了」を表示して、プレイヤーの入力を待つ
pressAnyKeyText.SetActive(true);
// キー入力は Input System(ファイル先 頭に using UnityEngine.InputSystem;)
while (Keyboard.current == null || !Keyboard.current.anyKey.wasPressedThisFrame)
{
yield return null;
}
operation.allowSceneActivation = true; // ここで初めてシーンが切り替わる
}
allowSceneActivation = trueにした瞬間にアクティベーションが始まり、isDoneがtrueになって新しいシーンが表示されます。
おまけ:先に知っておくと良いこと
シーン遷移を実装できるようになったら、次はこのあたりが課題になってきます。
- シーンをまたいでデータを持ち越したい: スコアやBGMは、シーンを切り替えると通常は消えてしまいます。
DontDestroyOnLoadで特定のオブジェクトを生き残らせるのが定番です。DontDestroyOnLoadの記事 で解説しています。 - シーンを「重ねて」ロードするAdditiveモード:
LoadScene(名前, LoadSceneMode.Additive)を使うと、今のシーンを消さずに別のシーンを追加できます。UIシーンを常駐させたり、広大なマップを分割ロードしたりする際の必須テクニックです。 - さらに柔軟なロード管理: 大規模になってきたら、シーンやアセットのロードを一元管理できる Addressables が視野に入ります。Addressables入門の記事 で概要を掴めます。
まとめ
シーン遷移は、ゲームの構造を定義する上で不可欠な機能です。
SceneManagerクラスを使ってシーンを遷移する。- ロードしたいシーンは、必ずビルド設定に追加しておく。
LoadScene(): シンプルな同期ロード。ロード中はゲームが停止する。LoadSceneAsync(): 高度な非同期ロード。ロード画面の実装に必須。
プレイヤーを待たせている間も、プログレスバーを表示したり、ゲームのヒントを表示したりすることで、待ち時間のストレスを軽減できます。ユーザー体験を向上させるためにも、LoadSceneAsyncを使いこなせるようになりましょう。