前回に引き続き、ブロック崩しの作成を行います。今回はゲームクリア/ゲームオーバー後にもう一度遊べるようにリトライ機能を実装します。
Unityプログラミング講座一覧はこちら

ゲームオーバー後のボタン入力処理

ゲームオーバーになった後にボタンを押すと再度プレイができるようにします。
GameOverスクリプトの変更
GameOverスクリプトを以下のように変更してください。
using UnityEngine;
using UnityEngine.UI;
// 追加
using UnityEngine.SceneManagement;
class GameOver : MonoBehaviour
{
    public Text gameOverMessage;
    // ゲームオーバーしたかどうかを判断するための変数
    bool isGameOver = false;
    void Update()
    {
        // ゲームオーバーになっている、かつ、Submitボタンを押したら実行する
        if(isGameOver && Input.GetButtonDown("Submit"))
        {
            // Playシーンをロードする
            SceneManager.LoadScene("Play");
        }   
    }
    void OnCollisionEnter(Collision collision)
    {
        gameOverMessage.text = "Game Over";
        Destroy(collision.gameObject);
        // isGameOverをtrueにする(フラグを立てる)
        isGameOver = true;
    }
}
ゲームオーバーになっていない状態でボタンを押しても、何も反応しないようにするために、ゲームオーバーになっているか/いないかを記憶しておくための変数isGameOverを用意しました。
ゲームスタート時にはisGameOverはfalseにし、ゲームオーバーになったらtrueにします。ゲームオーバーの判定処理を行っているOnCollisionEnterメソッド内にisGameOverをtrueにする処理を追加します。これで、isGameOverの値を確認すれば、ゲームオーバーになっているかどうかがわかるようになりました。
あとは毎フレーム呼ばれるUpdateメソッド内でゲームオーバー時にボタンを押すと処理が行われるようにif文を書けばOKです。入力処理にはInput.GetButtonDownメソッドを用いています(入力処理についての説明はこちら)。ここでは、Submitボタンを指定しました。デフォルトではスペースキーなどが割り当てられています。(InputMangaerで確認できます。)
リトライ機能の実装ですが、おそらく最も簡単であろう「シーンをロードし直す」方法を採用します。シーンのロードにはSceneManagerクラスのLoadSceneメソッドを使用します。
SceneManager.LoadScene(ロードするシーン);
シーンPlayをロードするには以下のようになります。
SceneManager.LoadScene("Play");
SceneManagerクラスは名前空間UnityEngine.SceneManagement内にありますので、名前空間UnityEngine.SceneManagementをusingで指定しましょう。
フラグ
変数isGameOverのように、ゲームの状態を管理する際に、「した/していない」を判定するための変数として「true/false」のどちらかの値を取るbool型の変数が良く使われます。
このような処理はフラグとも呼ばれ、falseだった値をtrueにすることをフラグを立てると言ったりします。
フラグは「条件を満たす」という意味合いのプログラミング用語でしたが、今では伏線や予測といった意味合いで広く用いられていますね。「フラグ回収」や「フラグが立った」という単語はどこかで見たことがあるのではないでしょうか。
ビルドマネージャーにシーンを登録する

Build Settingsに登録していないシーンをロードしようとするとエラーが起こるので注意が必要です。
メニューのFile->Build Settingsを開いて、PlayシーンをScenes In Buildの箇所にドラッグ&ドロップして登録を行いましょう。
Build Settingsに登録しなくてもロードできる場合
例外的に、再生中のシーンの再ロードは大丈夫なようです。つまり、PlayシーンからのPlayシーンのロードはエラーなしでできるみたいです。しかし、これはあくまで例外であることに気を付けてください。使用するシーンは全てBuild Settingsに登録するべきです。登録しないと他のシーンからPlayシーンをロードできない、ビルド(windowsならexeファイル化)できないなど、不具合が生じるので登録しておきましょう。
ゲームクリア後のボタン入力処理

ゲームクリアした際にもボタン入力でゲームをもう一度遊べるようにしましょう。
GameClearスクリプトを以下のように変更してください。
using UnityEngine;
using UnityEngine.UI;
// 追加
using UnityEngine.SceneManagement;
class GameClear : MonoBehaviour
{
    public Text gameClearMessage;
    Transform myTransform;
    // ゲームクリアしたかどうかを管理するフラグを用意
    bool isGameClear = false;
    void Start()
    {
        myTransform = transform;
    }
    void Update()
    {
        if (myTransform.childCount == 0)
        {
            gameClearMessage.text = "Game Clear";
            Time.timeScale = 0f;
            // ゲームクリアのフラグを立てる
            isGameClear = true;
        }
        // ゲームクリアしている、かつ、ボタン入力でシーンを再ロード
        if(isGameClear && Input.GetButtonDown("Submit"))
        {
            // timeScaleを1に戻しておく
            Time.timeScale = 1f;
            // シーンのロード
            SceneManager.LoadScene("Play");
        }
    }
}
基本的な処理はGameOverスクリプトの変更と同じです。ゲームクリアしたかどうかをbool型の変数isGameClearを用いて管理し、Submitボタン入力でPlayのシーンをロードするように書いています。
注意点はTimeScaleだけです。ゲームクリア時にはTimeScaleの値を0にしてゲームを停止しているので、再びゲームをスタートするためにはTimeScaleの値を1に戻す必要があります。
まとめ
今回は、ゲーム終了後にも再度ゲームを遊べるようにリトライ機能を実装しました。これで、繰り返し遊べるだけでなく、テストプレイ時にも毎回再生ボタンを押さずに済みます。次回はボールの挙動を改善します。
Unityプログラミング講座一覧はこちら

