前回までの作業でゲームとしては大体良い感じになってきました。しかしまだゲームオーバーなどの処理を実装していないため、ミスをしてもキャラクターが画面端から落ちていくだけでゲームがそのまま続いてしまいます。
そこでここでは
- プレイヤーがミスをしたらゲームオーバー画面を表示し、ゲームを中断する
- 「リトライ」ボタンを押したらゲームがリセットされて最初からゲームが始まる
といった処理を作っていきましょう。
ゲームオーバー画面のUIの作り方
まずはじめにゲームオーバー画面のUIを作ります。前回と同じ要領で新しいキャンバスを作り、「Game Over」というテキストを配置してください。また、その下にボタン(こちらも右クリック→「UI」→「古い機能」の中のものを使います)も配置してください。
できたら、このままではゲームオーバーでないときも表示されてしまい邪魔なのでキャンバスのゲームオブジェクトを非アクティブにしておきましょう。
ゲームオーバー処理のC#スクリプト
ではここでゲームオーバー処理のC#スクリプトを書いていきます。ゲームオーバー処理はゲーム進行に関わる処理なので、前回作ったGameManagerに処理を追加することにしましょう。
以下は「追加」と書かれている部分が追加部分です。なおすべてのソースコードを掲載すると長くなってしまうので適宜省略してあります。
using System.Collections; using UnityEngine; using UnityEngine.UI; public class GameManager : MonoBehaviour { [Header("必要なコンポーネントを登録")] [SerializeField] Transform playerTransform; [SerializeField] WallSpawner wallSpawner; [SerializeField] Text mileageText; [SerializeField] Text scoreText; [SerializeField] Text highScoreText; [SerializeField] Text levelText; // 追加 [SerializeField] GameObject gameOverCanvas; // 省略 // 追加 readonly string highScoreKey = "highScore"; // 省略 void InitGame() { Level = 1; Mileage = 0; maxScore = (int)Mathf.Pow(10, scoreDigits) - 1; //スコアの最大値を作成。例えば、8桁なら99999999 score = 0; highScore = PlayerPrefs.GetInt(highScoreKey, 0); //追加 timerIsActive = false; UpdateScoreUi(); wallSpawner.InitSpawner(); } // 省略 // ここから追加 public void GameOver() { playerTransform.gameObject.SetActive(false); wallSpawner.IsActive = false; gameOverCanvas.SetActive(true); if(timer != null) { StopCoroutine(nameof(MileageTimer)); timerIsActive = false; } IsActive = false; // ハイスコアのセーブ if(highScore > PlayerPrefs.GetInt(highScoreKey, 0)) { PlayerPrefs.SetInt(highScoreKey, highScore); PlayerPrefs.Save(); } } public void Retry() { gameOverCanvas.SetActive(false); StartGame(); } }
書けたら追加した「Game Over Canvas」欄にゲームオーバー用のキャンバスを登録しておきます。また、このままだとリトライボタンを押しても何も起きないので、ボタンを押したときにリトライ処理が実行されるようにボタンの「クリック時()」の欄にRetry関数を登録しておきましょう。
C#スクリプトの解説
追加した処理に関しても特に難しいことはやっていないのでコードを読んで頂ければわかると思うのですが、1点だけ注意点があります。それは「本当はPlayerPrefsは使うべきではない」という点です。
PlayerPrefsとはUnity標準のセーブ機能のことで、標準機能なのになんと色々な問題点があります。詳しい話は姉妹サイトのほうでしているのでここでは省略しますが…
簡単に言うと
- 動作が遅い
- 保存できるデータの型が限られていて不便
- セーブデータの保存場所がレジストリになる場合がある
とかまあそういう欠点があるわけです。
それで今回はなるべく簡単なコードになるようにと考えた結果として、やむなくハイスコアのセーブ処理にPlayerPrefsを使うことにしました。しかしこういう練習作のようなゲームならともかく、もし本格的にゲームを作るならちゃんとしたセーブ機能を導入したほうがよいということはお伝えしておきます。
ゲームオーバー判定用のトリガーの作成
さてこれでゲームオーバー処理ができましたが、まだゲームオーバー処理を呼び出すための仕組みを作っていないので何も起きません。そこでゲームオーバー判定用のトリガーを作りましょう。
まず空のゲームオブジェクトを作成し、そこに「Box Collider 2D」コンポーネントをアタッチしてサイズを適当に大きくし、「トリガーにする」にチェックを入れます。
次にゲームオーバー処理を呼び出すためのC#スクリプトを作ってこのゲームオブジェクトにアタッチします。
using UnityEngine; public class GameOverTrigger : MonoBehaviour { [SerializeField] GameManager gameManger; private void OnTriggerEnter2D(Collider2D collision) { if (collision.gameObject.CompareTag("Player")) { gameManger.GameOver(); } } }
そうしたら下の図のようにこのトリガーをシーンの左端に配置しておきましょう。
テストプレイして動作を確認しよう
では最後にテストプレイして動作を確認してみましょう。
- プレイヤーが画面端に押し出されたらゲームオーバー画面が出る
- リトライボタンを押したらゲームが再スタートする
- 一度再生モードを終了してもハイスコアがきちんと保存される
といった点をチェックしておいてください。