【Unity入門⑨】HPが0になったらゲームオーバーの演出をさせよう

Unity入門

前回の記事で、敵に触れたらダメージを食らうHPバーを作りました。
今回はプレイヤーのHPが0になったらゲームオーバになるUIを作ってみましょう!

この記事では、
プレイヤーのHPが0になったら画面に「GAME OVER」、「リトライ」ボタンを表示させる
・「リトライ」ボタン押したら初期位置にリスポーンする

のような仕組みを解説していきます!

完成イメージ

  • 画面中央に「GAME OVER」+「リトライ」ボタンを表示
  • リトライボタンを押すとシーンを再読み込みして最初からスタートできる

① UI を用意する(Canvas)

ゲームオーバーになった場合に表示させるUI(テキスト、ボタン)を作っていきましょう!

  1. Canvas を作成
    • Hierarchy → 右クリック → UI > Canvas
    • Render Mode:Screen Space – Overlay(そのままでOK)
    • ※自動で EventSystem も作られます(なければ UI > Event System を追加)
  2. 全画面の暗幕を作る
    • Canvas を右クリック → UI > Panel(名前:GameOverPanelにする)
    • Image の色を 黒 (0,0,0)Alpha=160/255 くらい(薄暗く)
    • Inactive(非アクティブ) にしておく(起動直後に見えないように)
  3. ゲームオーバー時のテキスト & リトライボタン
    • GameOverPanel の子に UI > Text (TMP)UI > Text(名前:Title
      • 文字:GAME OVER
    • GameOverPanel の子に UI > Button(名前:RetryButton、ラベル:RETRY
      👉「RETRY」ボタンを押したときに シーンを再読み込み(ゲーム再スタート) するため用のボタンです

<3.ゲームオーバー時のテキスト
テキストのサイズ、位置などを調整します。

<3.リトライボタン
ボタンの位置はPos X、Pos Yで調整します。


② MainManager.csの新規作成

ゲームオーバー時のUI表示、リトライをまとめて管理するMainManager.csを新規作成します📝(コピペOK)

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

public class MainManager : MonoBehaviour
{
    [Header("UI 参照")]
    [SerializeField] private GameObject gameOverPanel;   // ← GameOverPanel を割り当て
    [SerializeField] private Button retryButton;         // ← RetryButton を割り当て

    private bool _shown = false;

    private void Awake()
    {
        // 起動直後は非表示
        if (gameOverPanel != null) gameOverPanel.SetActive(false);

        if (retryButton != null)
            retryButton.onClick.AddListener(Restart);
    }

    // 外部(Player)から呼ぶ
    public void Show()
    {
        if (_shown) return;
        _shown = true;

        // パネルを出す
        if (gameOverPanel != null) gameOverPanel.SetActive(true);

        // 時間停止(UI演出は unscaledDeltaTime で動かす)
        Time.timeScale = 0f;

    }

    public void Restart()
    {
        // 時間を戻してからリロード
        Time.timeScale = 1f;
        SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex);
    }
}

③MainManagerのセットアップ

②で作成したスクリプトを管理する用のcreate Emptyオブジェクトを作成します。
(create Emptyはスクリプトだけ入れたい時等に使用される)

  1. MainManagerオブジェクトを作成する
    • Hierarchy → +ボタンクリック →「create Empty」で空のオブジェクトを作成する
    • 名前を「MainManager」に変更
  2. MainManager.csの適用
    • Add Component> MainManager.csを選択して適用する
  3. UIのセットアップ
    • 「gameOverPanel」 に CanvasのGameOverPanel をドラッグする
    • 「retryButton」 に CanvasのRetryButton をドラッグする

④Player からゲームオーバーを呼ぶ

Player.csにMainManager.csで追加した処理を呼び出します。
HP処理の _TakeDamage()0 以下になった瞬間に Show() を呼びます。(赤線)

using UnityEngine;
using UnityEngine.UI;
using UnityEngine.InputSystem; // Input System を使っている場合

public class Player : MonoBehaviour
{
    [SerializeField] private int _maxHP = 5;
    [SerializeField] private Image _hpBarFill;
    private int _currentHP;

    private MainManager _gameOver;
    private PlayerInput _input;

    void Start()
    {
        _currentHP = _maxHP;
        _UpdateHPBar();
        _gameOver = FindObjectOfType<MainManager>();
        _input = GetComponent<PlayerInput>();
    }

    private void OnCollisionEnter2D(Collision2D col)
    {
        if (col.collider.CompareTag("Enemy"))
        {
            _TakeDamage(1);
        }
    }

    // ダメージ処理
    private void _TakeDamage(int damage)
    {
        _currentHP -= damage;
        _currentHP = Mathf.Clamp(_currentHP, 0, _maxHP);

        _UpdateHPBar();

        if (_currentHP <= 0)
        {
            // 操作を止める
            if (_input != null) _input.enabled = false;

            // ゲームオーバーを表示
            if (_gameOver != null) _gameOver.Show();
        }
    }

    // HPバーの見た目を更新
    private void _UpdateHPBar()
    {
        if (_hpBarFill != null)
        {
            _hpBarFill.fillAmount = (float)_currentHP / _maxHP;
        }
    }
}

⑤各処理の説明(初心者向け)

各変数の説明

  • gameOverPanel
    → ゲームオーバー画面そのもの(背景+文字+ボタンなどをまとめたUI)
    → 表示・非表示を切り替える対象。
  • retryButton
    → 「RETRY」ボタン。押したらシーンを再読み込みします。
  • _shown
    → すでに表示したかどうかを覚えておくフラグ。
      (連続して何度も呼ばれないようにするため)

Awake()(起動直後に1回だけ実行される)

private void Awake()
{
    // 起動直後は非表示
    if (gameOverPanel != null) gameOverPanel.SetActive(false);

    // Retryボタンが押されたときにRestart()を実行する
    if (retryButton != null)
        retryButton.onClick.AddListener(Restart);
}
  • ゲーム開始時にゲームオーバー画面を非表示にする
    • SetActive(false) で見えなくする
  • Retryボタンの動きを登録する
    • retryButton.onClick.AddListener(Restart);
      → 「Retryボタンをクリックしたら Restart() を実行」という命令。

つまり、この Awake() で「初期状態」と「ボタンの動作」を設定しています。


Show()(ゲームオーバーを表示する)

public void Show()
{
    if (_shown) return;  // すでに表示中なら何もしない
    _shown = true;

    // パネルを有効化して表示
    if (gameOverPanel != null) gameOverPanel.SetActive(true);

    // ゲーム全体の時間を止める
    Time.timeScale = 0f;
}

これは プレイヤーがHP0になった瞬間に呼ばれる 関数です。
(Player.csから FindObjectOfType<MainManager>().Show(); で呼び出します)

  • _shown チェック
    → 何度も呼ばれないように制御(1回だけ実行)
  • gameOverPanel.SetActive(true)
    → ゲームオーバーUIを画面に表示!
  • Time.timeScale = 0
    → ゲーム全体を一時停止(プレイヤー・敵・物理挙動が止まる)

Restart()(リトライボタンを押したとき)

public void Restart()
{
    Time.timeScale = 1f; // 時間を元に戻す
    SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex); // 同じシーンを再読み込み
}

「RETRY」ボタンを押したときに呼ばれます。

  • Time.timeScale = 1
    → ゲームを再開できるように時間を元通りにする
  • SceneManager.LoadScene()
    → 今のシーンをリロードして最初からスタート!

これで「やり直し」ができるようになります。


全体の流れをまとめると…

手順処理担当関数
ゲーム開始パネル非表示、ボタン登録Awake()
HP0になるパネルを表示、時間停止Show()
RETRY押下時間再開、シーン再読み込みRestart()


⑥動作確認

  1. GameOverPanel を非アクティブにしておく(Startで有効化されないように)
  2. プレイして敵に触れ、HPを0にする
  3. 画面が暗転+GAME OVER、操作が止まり、RETRYでシーン再読み込み

👉HPが0になったらゲームオーバーUIを表示させ、リトライボタンでリスポーンすることが出来ました!!


⑦まとめ

処理名内容
Awake()最初にUIを非表示にして、Retryボタンの動作を登録
Show()ゲームオーバー画面を出して、時間を止める
Restart()時間を戻してシーンを再読み込み(リトライ)
  • GameOverPanel を用意して MainManager で表示・停止・再開を管理
  • Player 側は HPが0の瞬間だけ Show() を呼ぶ

コメント

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