学習記事一覧 · Unity基礎

【学習】スコアとゲームオーバー(UI 表示、リトライ)

これまでの学習では、

  • 落ち物キャッチゲームでスコア表示を学んだ
  • 横スクロールアクションでゲームオーバー時のシーン切り替えを学んだ

という形でゲームの流れを作ってきました。

しかし、ゲームオーバー画面でスコアを表示し、リトライできる 仕組みをまとめて学んでいません。

スコアとゲームオーバー画面

を完成させます。

今回は スコアの表示ゲームオーバー画面からのリトライ を学びます。

今日学ぶこと

  • スコアの表示 … ゲーム中とゲームオーバー画面の両方で表示
  • スコアの引き継ぎ … DontDestroyOnLoad でシーンをまたいで保持
  • リトライ … ボタンでゲームシーンを再読み込み
  • GameManager … ゲーム全体の状態を管理する

ゲームの流れ

タイトル画面(任意)

ゲーム画面(スコア表示、プレイ)

ゲームオーバー(スコア表示、リトライボタン)

リトライ → ゲーム画面に戻る

スコアをシーンをまたいで保持する

DontDestroyOnLoad を使うと、シーンを切り替えてもオブジェクトを残せます。

public class ScoreManager : MonoBehaviour
{
    public static ScoreManager Instance { get; private set; }
    public int Score { get; private set; }

    void Awake()
    {
        if (Instance != null)
        {
            Destroy(gameObject);
            return;
        }
        Instance = this;
        DontDestroyOnLoad(gameObject);
    }

    public void AddScore(int points)
    {
        Score += points;
    }

    public void ResetScore()
    {
        Score = 0;
    }
}

シングルトンにして、1つだけ存在するようにします。2つ目ができたら Destroy して重複を防ぎます。


ゲームオーバー画面の構成

  1. Canvas を作成
  2. Text で「ゲームオーバー」とスコアを表示
  3. Button で「リトライ」を配置
  4. リトライボタンの On Click で、ゲームシーンを読み込み+スコアをリセット(またはリトライ時はスコア維持)

スコアをゲームオーバー画面に表示する

ゲームオーバー画面のスクリプトで、ScoreManager からスコアを取得して表示します。

using UnityEngine;
using UnityEngine.UI;
using UnityEngine.SceneManagement;

public class GameOverUI : MonoBehaviour
{
    [SerializeField] private Text scoreText;
    [SerializeField] private Button retryButton;

    void Start()
    {
        if (ScoreManager.Instance != null)
        {
            scoreText.text = "スコア: " + ScoreManager.Instance.Score;
        }
        retryButton.onClick.AddListener(OnRetry);
    }

    void OnRetry()
    {
        if (ScoreManager.Instance != null)
        {
            ScoreManager.Instance.ResetScore();
        }
        SceneManager.LoadScene("GameScene");
    }
}

リトライで現在のシーンを再読み込みする

スコアをリセットせず、同じシーンを再度読み込むだけなら、次のようにします。

void OnRetry()
{
    SceneManager.LoadScene(SceneManager.GetActiveScene().name);
}

この場合、ScoreManager でスコアをリセットするかどうかは設計次第です。


ゲームオーバー時の処理(プレイヤー側)

プレイヤーがやられたときに、GameManager に通知する方法もあります。

// PlayerController など
void OnCollisionEnter2D(Collision2D collision)
{
    if (collision.gameObject.CompareTag("Enemy"))
    {
        FindObjectOfType<GameManager>().GameOver();
    }
}

GameManager.cs

using UnityEngine;
using UnityEngine.SceneManagement;

public class GameManager : MonoBehaviour
{
    public void GameOver()
    {
        SceneManager.LoadScene("GameOverScene");
    }
}

完成コード例(シンプル版)

スコアを DontDestroyOnLoad で持たず、ゲームオーバー時にスコアを渡す方法もあります。その場合は、静的変数で一時保持します。

// ScoreManager(ゲームシーン用)
public static int LastScore { get; private set; }

public void AddScore(int points)
{
    score += points;
    LastScore = score;
    scoreText.text = "スコア: " + score;
}

// GameOverUI(ゲームオーバーシーン用)
void Start()
{
    scoreText.text = "スコア: " + ScoreManager.LastScore;
}

※ この方法では、ゲームオーバーシーンに遷移した時点でゲームシーンのオブジェクトは破棄されるため、LastScore を static で保持しておく必要があります。


重要ポイント

スコアゲームオーバー の組み合わせで、ゲームの一連の流れが完成します。

  • DontDestroyOnLoad … シーンを切り替えてもオブジェクトを残す
  • シングルトン … スコア管理を1つにまとめる
  • リトライ … LoadScene でゲームシーンを再読み込み
  • スコアのリセット … リトライ時に 0 に戻すか、ハイスコアを残すかは設計次第

発展アイデア

  • ハイスコア … PlayerPrefs で保存し、ゲームオーバー画面に表示
  • タイトルに戻る … ゲームオーバー画面に「タイトルへ」ボタンを追加
  • ポーズ … Time.timeScale = 0 で一時停止、UI で再開
  • サウンド … ゲームオーバー時の SE、BGM の切り替え

スコアとゲームオーバーは ゲームの締めくくり です。ここまでで Unity 2D の基本は一通り押さえられます。