【Unity入門】超簡単!別のシーンへ切り替える方法

ゲームにはタイトル画面やゲーム中の画面など様々な「シーン」があります。

このシーンを切り替えることでユーザーにその状況に必要な画面へ誘導することができます。

今回の記事ではUnityを使ってシーンを切り替えるということについて解説していきたいと思います。

本記事を読めば、

・シーンの切り替え方がわかる
・エフェクトを付けたシーンの切替方法

がわかり、さらに

・シーン切り替え時に変数の値を引き継ぎたい
・シーン切り替えを行うと重くなってしまう場合とその対処法

について解説を行います。

この記事を読んでゲーム作成に重要なシーン切り替えについて学んでいきましょう!

目次

Unityでシーン切り替えをしてみよう

まず、シーンの切り替えを行ってみましょう。

今回のサンプルでは新規でプロジェクト作成後、Assets内に「TitleScene」と「MainScene」というSceneを用意しています。

また、BlueとGreenというMaterialとTitleSceneというC#のソースコードも用意しています。

TitleSceneが表示されてから1.5秒後にMainSceneへ切り替えるというサンプルを作ってみます。

シーンを登録しよう

まず最初にやらなければならないのはシーンの登録です。

メニューのFile→BuildSettingsを選択しましょう。

そして出てきたシーンへ、先ほど作ったシーンを投げ込みます。(もしくは該当シーンを開いたのちにAdd Open Scenesボタンで追加しましょう。)

オブジェクトとスクリプトの準備

TitleScene
unity_scene_1

TitleSceneではSphereオブジェクトを作成し、BlueというMaterialを設定してあります。
unity_scene_2

MainScene
unity_scene_3

MainSceneにはCylinderオブジェクトを作成し、GreenというMaterialを設定してあります。
unity_scene_4

次に、プログラムを見ていきましょう。

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

public class TitleScene: MonoBehaviour {

    // Use this for initialization
    void Start () {
        Invoke("ChangeScene", 1.5f);
    }
    
    // Update is called once per frame
    void Update () {
        
    }

    void ChangeScene()
    {
        SceneManager.LoadScene("MainScene");
    }
}

※コードについての解説は後半解説します

コードが書けたらエディタ画面に戻り、Hierarchyタブで右クリック→CreateEmptyでGameObjectにを新規作成します。

そして下図のようにC#のコードをドラッグアンドドロップして処理を割り当てます。
unity_scene_5

ちなみにこのドラッグアンドドロップ以外にも割り当てる方法があるので解説しておきます。
GameObjectをクリックしてAddComponentをクリック
unity_scene_6

クリックすると次のようにComponentを追加する小ウインドウがでてくるため、
unity_scene_7

Scriptsを選択します。
そうするとTitleSceneというファイル名が出てくるのでそれを選択すると割り当てることができます。

unity_scene_8

では早速、実行してみましょう。

unity_scene_9

無事実行できましたね!

さて、先程解説したプログラムですがもう一度みてみましょう。

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

public class TitleScene: MonoBehaviour {

    // Use this for initialization
    void Start () {
        Invoke("ChangeScene", 1.5f);
    }
    
    // Update is called once per frame
    void Update () {
        
    }

    void ChangeScene()
    {
        SceneManager.LoadScene("MainScene");
    }
}

このプログラムで何をしているのか解説をしていきます。

まずStartメソッドでInvokeというメソッドを読んでいますがこのメソッドは数秒後に処理を実行するというメソッドになります。

今回の場合は1.5秒後にシーンを切り替えたいのでこの処理を書きました。

そして、ChangeSceneメソッドですがこの中にSceneManager.LoadSceneと書いてある部分があります。

この部分がシーンを切り替える処理になります。
切り替えたいシーン名を指定することでシーンを切り替えることができます。

このメソッドが呼ばれた瞬間にシーンの切り替えが始まり、実行結果通りシーンの切り替えが発生するようになっています。

シーン切り替えのTips

シーン切り替えで変数の値を引き継ぎたい

さて、シーンの切替方法はわかっていただけたと思います。

この項ではシーンを切り替えたあとに前のシーンの変数を使いたいといった場合にどうすればよか解説していきます。

具体的にどういった場面で使うかですが、例えばゲームオーバーになった場合にメインのゲーム画面からゲームオーバーの画面に移るとします。

そのゲームオーバーの画面でスコアなどを表示したい時にメインのゲーム画面で保持しているスコアを引き継ぎたい場合などがあるかと思います。

では早速ソースコードをみてみましょう。

メイン画面でのコード

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

public class MainScene: MonoBehaviour {

    protected static int Score = 0;

    void Start () {
    }

    void Update () {
        // 何らかのゲームの処理があるとします
    }

    void ChangeScene()
    {
        SceneManager.LoadScene("GameOverScene");
    }

    public static int GetScore()
    {
        return Score;
    }

}

ゲームオーバー画面でのコード

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class GameOverScene : MonoBehaviour
{

    void Start()
    {
    }

    void Update()
    {
        // 何らかのゲームの処理があるとします


        // タイトルシーンで保持しているスコアを取得
        int score = TitleScene.GetScore();
    }
}

このサンプルではMainSceneに静的な変数Scoreを用意しています。

このstatic変数を用意することで値を保持し続けます。

そして、GameOverSceneからTitleSceneクラスのGetScoreメソッドを呼び出していますが問題なく変数scoreに値を取得することができています。

ただし、このstatic変数を使うということはゲーム開始時などで値を初期化するなど、しっかり管理しなければ思わぬバグの元になる可能性があります。

その点は注意した上で使いましょう!

次の項ではシーン切替時のあるある、動作が重くなる現象について解説していきます。

シーン切り替えで動作が重くなる

PC版のUnityなどではシーン切替時に重くならないが、AndroidやiOSで動かしてみたらシーン切り替えがもっさりとしているなどの問題が起きる場合があります。

原因はなんでしょうか?

シーンを読み込む際に今まで使用していたシーンのメモリを解放や次のシーンを読み込む際のリソース読み込みなど様々な理由があるかと思われます。

ゲームの規模が大きくなるに連れてその負担が大きくなる可能性があり、開発中に以下にユーザーにとって負担にならないかを検討する必要があります。

たとえば、この記事の冒頭で使ったサンプルではSceneManager.LoadSceneを使用したと思います。

このメソッドは呼び出された瞬間にシーンの読み込みを行いますが読み込むシーンが重ければ切替時に負荷がかかりユーザーにとってはもっさりとした動作になる可能性があります。

そのため、SceneManager.LoadSceneAsyncを使うなど非同期処理を行うことで解消される可能性があるでしょう。

SceneManager.LoadSceneAsyncを使うと通常の処理を行いながら裏でシーンを読み込み、読み込みが終わったタイミングでシーンを切り替えるという形になります。

多くのリソース大規模なゲーム開発を想定している場合はこういった点に注意が必要ですね。

エフェクトをつけてシーンの切り替えをしたい

最後にシーンを切り替える際にエフェクトを付けてシーンを切り替えたい場合どうすればよいかという点について解説します。

よくゲームではシーン切り替え時にフェードインフェードアウトズームインズームアウトなどといった視覚的な効果で演出することがあります。

こういった要素はユーザーの気分を盛り上げることにもなるため案外重要です。

ではUnityではどういった形で実装するのが良いでしょうか?

答えとしては有志がいくつか便利に使える処理を作ってくれているのでそういったものを利用すると簡単に実現することができるでしょう。

例えば、フェードイン・フェードアウトで言えば

【Unity】シーン遷移時のフェードイン・フェードアウトを実装してみた
https://naichilab.blogspot.jp/2013/12/unity.html

が参考になるかと思います。

またFadeCameraを使うことで変わったエフェクトを実装することもできます!

【Unity】Unityでトランジションを使用した綺麗な場面転換(uGUI対応版)
http://tsubakit1.hateblo.jp/entry/2015/11/04/015355

まとめ

いかがだったでしょうか?

シーンの切り替えの基本的な方法からシーン切り替えを行う際に重くなる現象の解決法などシーン切り替えについての情報についてお届けしてきました。

シーン切り替えはゲーム開発では必須の技法なので必ず覚えておきましょう!

この記事を書いた人

30歳、フリーランスプログラマ。中学の頃よりプログラミングに興味を持ちゲーム開発やWebサイト構築などを経験
新しいフレームワークやライブラリに興味があり革新的な機能が含まれていると泣いて喜ぶ。

目次