Unity入門

【Unity】シーン管理 | SceneManager、切り替え、LoadScene、LoadSceneAsync、DontDestroyOnLoad、メモリ最適化

Unityでゲームを作る際、タイトル画面 → ゲームシーン → 画面結果など、シーンの切り替えが必要になります。

  • ボタンを押して次のシーンへ移動したい!
  • ロード画面を作って、シーンをスムーズに切り替えたい!
  • シーンを切り替えてもデータを保持したい!

UnityではSceneManager使うことで、簡単にシーンを切り替えたり、非同期ロードを行うことが可能です
この記事では、シーンの基本操作から、ロード画面の作成、データの引き継ぎ方法、パフォーマンス最適化までを詳しく解説します!

この記事でわかること

  • SceneManagerを使ったシーンの切り替え方法
  • シーンの非同期ロード(ロード画面の作成)
  • DontDestroyOnLoadを使ったデータの引き継ぎ
  • シーン管理の最適化テクニック

Unityのシーン管理(SceneManager)

シーン(Scene)とは?

シーン(Scene)は、ゲームの各シーン(タイトル画面・ステージ・結果画面)を管理する単位です

ゲーム全体を1つのシーンで作るのではなく、複数のシーンに分割すると管理しやすい!
シーンごとにオブジェクトを整理し、ロード・切り替えがスムーズに!

Unity シーン管理の画像

※ この他にも以下のサイトを参考にしてください。

シーン(Scene)の作成、保存

① Projectから追加

  1. [Project] → [Scenesフォルダ] → [右クリック] → [Create] → [Scene] → [Scene] を選択
  2. Scenesフォルダ内にシーン(Scene)が追加される
  3. シーン(Scene)名を入力して決定
Unity シーンの作成、保存の画像

シーン(Scene)を追加する方法

シーンを追加しないと、SceneManager.LoadScene()で読み込まないので注意!

  1. File→Build Settings開く(Unity6だとBuild Profiles
  2. Scenes In Buildに最新シーンをドラッグ&ドロップか「Add Open Scemes」で追加(Unity6だとScene List
  3. シーンの順番を調整し、Build & Run実行可能にする
Unity シーンの追加の画像

シーン(Scene)の切り替え

SceneManager.LoadScene()でシーン切り替え(同期)

ボタンにChangeScene()設定すれば、クリックでシーン遷移可能!

using UnityEngine;
using UnityEngine.SceneManagement;

public class SceneChanger : MonoBehaviour
{
    public void ChangeScene()
    {
        SceneManager.LoadScene("GameScene"); // シーン名で指定
    }
}

LoadSceneAsync()でシーン切り替え(非同期)

シーンのロード時にカクつきを防ぐため、LoadSceneAsync()を使って非同期でシーンを読み込むのがベスト!

進行状況(operation.progress)をスライダーで表示!
ロード画面を見せることで、ユーザー体験を向上!

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

public class SceneLoader : MonoBehaviour
{
    // ローディング画面の UI(非アクティブ状態で設定しておく)
    public GameObject loadingScreen;

    // 読み込み進捗を表示するスライダー
    public Slider progressBar;

    // シーンをロードするメソッド(ボタンなどから呼び出す)
    public void LoadScene(string sceneName)
    {
        // 非同期シーンロードのコルーチンを開始
        StartCoroutine(LoadSceneAsync(sceneName));
    }

    // 非同期でシーンをロードするコルーチン
    IEnumerator LoadSceneAsync(string sceneName)
    {
        // ローディング画面を表示
        loadingScreen.SetActive(true);

        // シーンの非同期ロード開始
        AsyncOperation operation = SceneManager.LoadSceneAsync(sceneName);
        
        // シーンのロードが完了するまで進捗を更新
        while (!operation.isDone)
        {
            // operation.progress は 0.0 ~ 0.9 の範囲(1.0 には到達しない)
            progressBar.value = operation.progress;

            // 次のフレームまで待機
            yield return null;
        }
    }
}

シーン間でデータを保持する方法

DontDestroyOnLoad()を使う

シーンを待ちたいでもオブジェクトを消さない方法として、DontDestroyOnLoad()を使います。

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を使ってスコアを保存する(非推奨)

PlayerPrefsを使うと、シーンが切り替わってもデータを永続的に保存できる。
※ PlayerPrefsはUnityから非推奨とされています。

PlayerPrefs.SetInt("HighScore", 100);  // 保存
int highScore = PlayerPrefs.GetInt("HighScore", 0);  // 読み込み

シーン管理の最適化

メモリ最適化(不要なオブジェクトの削除)

シーン移行後に不要なオブジェクトを削除することで、メモリ使用量を削減することが可能です。

void OnSceneLoaded(Scene scene, LoadSceneMode mode)
{
    Resources.UnloadUnusedAssets();
}

よくあるエラーと解決策

SceneManager.LoadScene()が動作しない

解決策:Build Settingsにシーンを追加する!
解決策:シーン名スペルミスをチェック!

シーンが切り替わると変数がリセットされる

解決策:DontDestroyOnLoad()でデータを保存!
解決策:PlayerPrefsでデータを保存!

まとめ

SceneManager.LoadScene()を使えば簡単にシーン移行できる!
非同期ロード( LoadSceneAsync())を使えるとロード画面ができる!
DontDestroyOnLoad()を使えばデータを保持可能!
UIを別シーンに一時的に、シーンロードを高速化!