Developer

【Unity実践】#10 プロトタイプ編 ~ シーンの制御 part2 ~【Boxゲーム】
2021.02.05
Lv2

【Unity実践】#10 プロトタイプ編 ~ シーンの制御 part2 ~【Boxゲーム】

今回の内容

前回に引き続き、シーン制御の仕組みを実装します。
今回の内容は、ボタンのクリックイベントが主役となります。

※初めての方はこちらから
【第1回記事】この連載について

デバッグ機能を実装

前回、isClear、isGameOver の時に対応する UI が表示される仕組みを作成しました。
今回はその先の処理を作成するのですが、現状、isClear や isGameOver を操作する仕組みが有りません。

後に、ゴールやトラップと言ったオブジェクトを作成すると、
それらに触れた、踏んだ時などにこれらのフラグを切り替える形となりますが、
もう少し先のお話になるので、それまでの間は isClear や isGameOver の切り替えはデバッグボタンで行います。

新規スクリプトを Assets > Script 以下に作成して名前は DebugModeScript とします。

以下を記述してください。

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

public class DebugModeScript : MonoBehaviour
{
    // デバッグ用のリトライボタンが押されたとき
    public void OnRetryButtonClick()
    {
        StageControllerScript.isGameOver = true;
    }

    // デバッグ用のクリアーボタンが押されたとき
    public void OnClearButtonClick()
    {
        StageControllerScript.isClear = true;
    }
}

記述ができたら、Canvas > Debug にアタッチしましょう。

各メソッドが、デバッグUIの「Retry」「Next」ボタンクリック時に呼び出されるようにします。

Canvas > Debug > DebugRetryButton の「Button」コンポーネントで、
OnClick の処理にさきほどの「OnRetryButtonClick」メソッドを設定します。

<↑ の操作動画>

動画を再生するには、videoタグをサポートしたブラウザが必要です。

同様に、DebugClearButtonに「OnClearButtonClick」メソッドを設定します。

シーンを再生して、Retryボタンクリック時にリトライ画面、
Clearボタンクリック時にクリア画面が表示されることを確認してください。

動画を再生するには、videoタグをサポートしたブラウザが必要です。

<関連記事>
【Unity連載】uGUI(Button)の使い方を詳しく解説

リトライの処理

前回作成した、StageControllerScriptに以下を追記します。(73~77行目)

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

public class StageControllerScript : MonoBehaviour
{
    public const string GAME_SCENE_NAME = "GameScene"; // シーン名のプレフィクス
    public const int GAME_SCENE_COUNT = 1;             // シーンの数

    private int stageNum;    // 現在のステージ数
    public Text stageName;      // 現在のステージ名("Stage" + stageNum)

    public static bool isClear;   // クリアフラグ
    public static bool isGameOver;   // ゲームオーバーフラグ

    public GameObject clearCanvas;   // クリア時のUI
    public GameObject retryCanvas;   // ゲームオーバー時のUI

    // デバッグ用
    private bool isDebug = true;     // デバッグフラグ
    public GameObject debugCanvas;   // デバッグメニューのUI

    void Start()
    {
        // ステージ数(画面表示用 ※実際のシーン名とは必ずしも対応しない!)
        stageNum = PlayerPrefs.GetInt("StageNum", 1);
        stageName.text = "Stage" + stageNum;

        // 自分のシーンではない場合、ロードし直す
        if (GetLoadSceneName() != SceneManager.GetActiveScene().name)
        {
            LoadScene();
        }

        // 初期化
        isClear = false;
        isGameOver = false;

        // デバッグモード表示の切り替え
        debugCanvas.SetActive(isDebug);
    }

    void Update()
    {
        // クリアしたとき
        if (isClear)
        {
            ShowClearCanvas();
            enabled = false;
        }
        // ゲームオーバーのとき
        else if (isGameOver)
        {
            ShowRetryCanvas();
            enabled = false;
        }
    }

    // クリアUIを表示する
    private void ShowClearCanvas()
    {
        clearCanvas.SetActive(true);
    }

    // リトライUIを表示する
    private void ShowRetryCanvas()
    {
        retryCanvas.SetActive(true);
    }

    // Retryボタンをクリックしたときの処理
    public void OnRetryButtonClick()
    {
        LoadScene();
    }

    // ロードするシーン名を取得
    private string GetLoadSceneName()
    {
        int loadSceneNum = PlayerPrefs.GetInt("SceneNum", 1);
        return GAME_SCENE_NAME + loadSceneNum;
    }

    // ステージを読み込む処理(現在のstageNumに対応するステージ)
    private void LoadScene()
    {
        SceneManager.LoadScene(GetLoadSceneName());
    }
}

リトライ時は単純に、今のシーンを呼びだす処理を実装しています。
前回作成した LoadSceneメソッドを使ってるだけですが、仕組みを忘れてしまった方は再確認しましょう。

大事なのはこの後で、この処理が「Retry」ボタンクリック時に呼び出されるようにします。
Canvas > Retry > RetryButtonの「Button」コンポーネントで、
OnClickの処理にさきほどの「OnRetryButtonClick」メソッドを設定します。

<↑ の操作動画>

動画を再生するには、videoタグをサポートしたブラウザが必要です。

シーンを再生してデバッグの Retryボタンをクリックしてリトライ画面を表示しましょう。
リトライ画面の Retryボタンをクリックして、シーンが再読み込みされれば成功です。

動画を再生するには、videoタグをサポートしたブラウザが必要です。

クリアの処理

StageControllerScript に OnNextButtonClickメソッドを追加します。(73~93行目)
こちらはリトライと違ってやや複雑で、以下の処理を行います。
・PlayerPrefs の StageNum をプラス1する
・PlayerPrefs の SceneNum を更新する。(全ステージクリアまでは順番通り、それ以降はランダム)
・シーンを読み込む(LoadSceneメソッド)

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

public class StageControllerScript : MonoBehaviour
{
    public const string GAME_SCENE_NAME = "GameScene"; // シーン名のプレフィクス
    public const int GAME_SCENE_COUNT = 1;             // シーンの数

    private int stageNum;    // 現在のステージ数
    public Text stageName;      // 現在のステージ名("Stage" + stageNum)

    public static bool isClear;   // クリアフラグ
    public static bool isGameOver;   // ゲームオーバーフラグ

    public GameObject clearCanvas;   // クリア時のUI
    public GameObject retryCanvas;   // ゲームオーバー時のUI

    // デバッグ用
    private bool isDebug = true;     // デバッグフラグ
    public GameObject debugCanvas;   // デバッグメニューのUI

    void Start()
    {
        // ステージ数(画面表示用 ※実際のシーン名とは必ずしも対応しない!)
        stageNum = PlayerPrefs.GetInt("StageNum", 1);
        stageName.text = "Stage" + stageNum;

        // 自分のシーンではない場合、ロードし直す
        if (GetLoadSceneName() != SceneManager.GetActiveScene().name)
        {
            LoadScene();
        }

        // 初期化
        isClear = false;
        isGameOver = false;

        // デバッグモード表示の切り替え
        debugCanvas.SetActive(isDebug);
    }

    void Update()
    {
        // クリアしたとき
        if (isClear)
        {
            ShowClearCanvas();
            enabled = false;
        }
        // ゲームオーバーのとき
        else if (isGameOver)
        {
            ShowRetryCanvas();
            enabled = false;
        }
    }

    // クリアUIを表示する
    private void ShowClearCanvas()
    {
        clearCanvas.SetActive(true);
    }

    // リトライUIを表示する
    private void ShowRetryCanvas()
    {
        retryCanvas.SetActive(true);
    }

    // Nextボタンをクリックしたときの処理
    public void OnNextButtonClick()
    {
        // ステージ数を加算
        stageNum++;
        PlayerPrefs.SetInt("StageNum", stageNum);

        // 次に読み込むシーン
        // 全ステージクリア後は、ランダムにする
        if (stageNum > GAME_SCENE_COUNT)
        {
            int rnd = Random.Range(1, GAME_SCENE_COUNT + 1);
            PlayerPrefs.SetInt("SceneNum", rnd);
        }
        else
        {
            PlayerPrefs.SetInt("SceneNum", stageNum);
        }

        LoadScene();
    }

    // Retryボタンをクリックしたときの処理
    public void OnRetryButtonClick()
    {
        LoadScene();
    }

    // ロードするシーン名を取得
    private string GetLoadSceneName()
    {
        int loadSceneNum = PlayerPrefs.GetInt("SceneNum", 1);
        return GAME_SCENE_NAME + loadSceneNum;
    }

    // ステージを読み込む処理(現在のstageNumに対応するステージ)
    private void LoadScene()
    {
        SceneManager.LoadScene(GetLoadSceneName());
    }
}

これも前回の記事で説明していた内容ですが、
PlayerPrefs の SceneNum を更新した上で LoadSceneメソッドを呼び出すことで、次のシーンが読み込まれます。

Retryボタンと同様に、Canvas > Clear > NextButtonの「Button」コンポーネントで、
OnClickの処理にさきほどの「OnNextButtonClick」メソッドを設定します。

シーンを再生して、デバッグの Clearボタンをクリックしてクリア画面を表示しましょう。
「Next」ボタンをクリックして、画面上部のステージ番号が増えている事、
シーンが再読み込みされていれば成功です。

動画を再生するには、videoタグをサポートしたブラウザが必要です。

今は1シーンしかないので、シーンの切り替わりは次回以降で確認しましょう。

おわりに

前回と今回で、シーンの制御に関する処理はおおよそ完成となります。
次回はゴールとトラップを作成して、デバッグ機能を使っていた箇所を置き換えたいと思いますのでお楽しみに!

 
 

連載目次リンク

実践Unityゲームプログラミング 連載目次
 

関連する連載リンク

「初心者のための」Unityゲーム制作 目次
 

© Unity Technologies Japan/UCL