【Unity入門⑭】ゴールに触れたらゲームクリア!ゴールUIを表示しよう

Unity2D入門シリーズ

こんにちは!夜の街2Dアクションゲームを制作中の怪獣です🦖
今回は、
プレイヤーがゴールオブジェクトに触れたら「ゲームクリアUI」を表示する方法
を解説します。

ゲームでは、
「敵に当たったらゲームオーバー」、「ゴールにたどり着いたらゲームクリア」という流れが基本になりますよね。

この記事では、

  • ゲームクリアUIの作成
  • Playerがゴールに触れたかどうか判定させる処理をつくる
  • MainManagerでUIを表示させる処理をつくる
  • SPACEキーを押すとシーンを最初からやり直す

という流れで作成~表示させるところまで解説を進めていきます!


この記事でやること

  • ゲームをクリアしたときのUIを作成する
  • ゴールオブジェクトを作成する
  • Playerがゴールに触れたらゲームクリアUIを表示させる
  • SPACEキーを押すと最初からスタート

① ゲームクリアUIを作成しよう

まずはUIの土台となるCanvasを作ります。

Canvas(キャンバス)とは、一言でいうと
Unityで「UIを表示するための土台(画面)」です。

テキスト、ボタン、パネルなどの UI要素は、必ず Canvas の子オブジェクトとして配置されます。

Canvas を作成

  1. Hierarchy を右クリック
  2. UI → Canvasを追加

GameClearPanel を作る

クリア時に画面に表示させるベースとなるパネルを作ります。

  1. Canvas の子に UI → Panel を作成する
  2. 名前を GameClearPanel に変更
  3. 背景色を半透明の黒にするのがおすすめです(Colorで調整)

テキストを配置する

クリア時に画面に表示させる文字を作ります。

  1. GameClearPanel の子に UI → Text (TextMeshPro)を追加
  2. テキストを GAME CLEAR!! などに変更
  3. 中央寄せ・大きめフォントに調整する

必要であれば

  • 「次へ」ボタン
  • 「タイトルへ戻る」ボタン

を追加してもOKです。


最初は非表示にする

  • GameClearPanel
    チェックを外して非アクティブにしてください。(ゲーム開始時に表示されてしまうため)

②MainManager に 処理を追加する

次に、 MainManagerに以下の処理を作成します。(コピペOK!)

  • ゲームクリア時のUIを表示させる処理
  • SPACEキーを押すとシーンを最初からやり直す処理

MainManager は主に以下のような役割をします。

  • ゲーム全体の状態管理する
  • UI の表示・非表示を制御など
using UnityEngine;

public class MainManager : MonoBehaviour
{
    [Header("UI参照")]
    [SerializeField] private GameObject _gameClearPanel;
    
    private bool _isGameClear = false;

    private void Awake()
    {
        // 念のため起動時は非表示
        _gameClearPanel.SetActive(false);
    }
    
    void Update()
    {
        // ゲームクリア後、SPACEキーが押されたらリスタート
        if (_isGameClear && Input.GetKeyDown(KeyCode.Space))
        {
            RestartScene();
        }
    }

    // ゲームクリアUIを表示する
    public void ShowGameClearUI()
    {
        _gameClearPanel.SetActive(true);
        _isGameClear = true;
    }
    
    // シーンを最初から読み直す
    private void RestartScene()
    {
        SceneManager.LoadScene(SceneManager.GetActiveScene().name);
    }
}

各処理の解説

[SerializeField] private GameObject _gameClearPanel;
  • SerializeFieldを定義してUnity上のInspector から設定できるようにしています

上記を定義したら、Unity上から①で作成したGameClearPanelドラッグ&ドロップしてください!


private bool _isGameClear = false;

ゲームクリア状態かどうか判断するようのフラグです。
後の処理で、ゲームクリアしている状態(true)だったらSPACEキーを受け付けるようにしています。


private void Awake()
{
    _gameClearPanel.SetActive(false);
}

Awake は「シーンが始まった瞬間」に必ず1回だけ呼ばれます💡

  • シーン起動時に 必ず非表示にする
  • こうするとInspector 設定ミスを防げる

private void Update()
{
    if (_isGameClear && Input.GetKeyDown(KeyCode.Space))
    {
        RestartScene();
    }
}

Updateは毎フレーム呼ばれます。

  • キー入力は 毎フレーム監視する必要がある
  • ゲームクリア後だけ受付するように条件を付けています

private void RestartScene()
{
    SceneManager.LoadScene(SceneManager.GetActiveScene().name);
}
  • 今開いているシーン名を取得
  • そのシーンを再ロード

➡️ 「最初からスタート」=シーンを再読み込みということをしています。


public void ShowGameClearUI()
{
    _gameClearPanel.SetActive(true);
    _isGameClear = true;
}
  • ゲームクリア時に呼ばれる(Player側で判断します)
  • UI を表示するだけのシンプルな責務
  • _isGameClearをtrueに更新し、クリア状態にしている

他にもこのあとに

  • SE 再生
  • BGM 停止
  • フェード演出

を追加する場合も、ここに書けばOKです!

③ゴールオブジェクトを作る

ゴール用オブジェクトを作成

  • Hierarchyで「2Dオブジェクト → Sprite → Square」を作成する(名前はGoalにする)
  • Add Componentでコンポーネントを追加
    • BoxCollider2D などの Collider2D を追加
    • Rigidbody2D(物理挙動を持たせておく)
      • Body TypeはStaticにしておきます(オブジェクトが動かないようにするため)
  • Sprite Rendererタブで「Sprite」にゴール用の画像をドラッグする

「Goal」タグを追加して設定する

  1. Inspector の Tag からAdd Tagを押す
  2. 「+」ボタンでGoal タグを追加する

Goal タグを追加したらゴールオブジェクトに設定してください。


④Player.csにゴールの当たり判定処理を作る

次に、プレイヤーがゴールに触れたことを検知する処理OnCollisionEnter2Dメソッド内に作成します。

OnCollisionEnter2D
Collider2D 同士が接触した瞬間に呼ばれるUnityの共通メソッドです。

今回のように、「敵に当たった」「ゴールに触れた」といった判定をすることが出来ます。

public class Player : MonoBehaviour
{
    
    private void OnCollisionEnter2D(Collision2D collision)
    {
        // 敵に触れたときの処理
        if (collision.gameObject.CompareTag("Enemy"))
        {
            _HitEnemy(collision.gameObject);
        }
        // 追加
        // ゴールに触れたときの処理 
        else if (collision.gameObject.tag == "Goal")
        {
            FindObjectOfType<MainManager>().ShowGameClearUI();

            // プレイヤーを非アクティブにする
            enabled = false;
            GetComponent<PlayerInput>().enabled = false;
        }
    }
}

各処理の解説


        // ゴールに触れたときの処理 
        else if (collision.gameObject.tag == "Goal")
        {
            FindObjectOfType<MainManager>().ShowGameClearUI();

            // プレイヤーを非アクティブにする
            enabled = false;
            GetComponent<PlayerInput>().enabled = false;
        }
  • tag名が“Goal”に設定されたオブジェクトに触れたか判定
  • 触れた場合、シーン上に存在する MainManager を探して取得する
  • ShowGameClearUI() で、ゲームクリア用の UI をMainManager から表示する
  • BGM 停止や効果音再生などもここでまとめて管理ができます

enabled = false;
GetComponent<PlayerInput>().enabled = false;
  • Player スクリプト自体を停止(ゴール後に操作できないようにする)
  • Update や移動処理が動かなくなる

ゴール後も動けてしまうと、演出が壊れてしまうため必須の処理です。


動作確認

ゴールオブジェクトに触れて、UIを表示することができました!

まとめ

  1. ゴールに触れたら GAME CLEAR!! UI を表示
  2. プレイヤー操作を停止
  3. SPACEキーを押すとシーンを最初からやり直す

最後まで読んでいただきありがとうございました。

これで、「遊ぶ → クリア → もう一回」という、
ゲームとして最低限必要なループが完成しました!

この記事が少しでもゲーム制作のお役に立てたら嬉しいです🦖

コメント

タイトルとURLをコピーしました