【学習】スコアとゲームオーバー(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 して重複を防ぎます。
ゲームオーバー画面の構成
- Canvas を作成
- Text で「ゲームオーバー」とスコアを表示
- Button で「リトライ」を配置
- リトライボタンの 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 の基本は一通り押さえられます。