前回までの作業で、今回のゲームもだいぶシューティングゲームらしくなってきました。しかし今のままでは
- ページの読み込みと同時に突然ゲームが始まることになってしまう
- まだゲームオーバー処理を作っていないので、プレイヤーが隕石と衝突しても何も起こらない
というような状態であり、やはりまだまともに遊べるとは言いがたいです。そこでここでは
- タイトル画面を表示して、ボタンをクリックしたらゲームが始まるようにする
- 自機が隕石と衝突したらゲームオーバー画面を出す
- ゲームオーバー画面でボタンをクリックすると再びゲームが始まるようにする
といった処理を作っていきましょう。
タイトル画面とゲームオーバー画面のUIの作り方
ではまずはタイトル画面やゲームオーバー画面のUIを作ります。
まずはタイトル画面です。シーンに新しいキャンバスを作り、その子として下の画像のようにテキストとボタンを作って配置してください。
そしてデフォルトだと、タイトル文字のテキストやボタンの子のテキストのフォントが「Arial」になっていると思うのですが、これを最初にインポートしてもらった任意の日本語フォント(私の場合はM+フォント)に変更しましょう。これでWebGLで日本語が表示されなくなる問題を回避することができます(※もっとも、お手本では日本語の文字を使っていないので関係ないですが…)。
さてお次はゲームオーバー画面です。先ほどのタイトル画面を複製して、下の画像のようにテキストを変更してください。
これで必要な画面のUIができました。この2つはあとでスクリプトから必要なときにアクティブ状態にするので、ひとまず両方とも非アクティブ状態にしておいてください。
GameManager(ゲームマネージャー)の作り方
そうしたら次は「GameManager」というゲームの監督のような役割をするゲームオブジェクトを作ります。これはUnityでゲームを作るときはよく登場する概念なので、初めてだという方はぜひ覚えて帰っていただきたいと思います。
GameManagerとは?
まずGameManagerについて簡単に説明します。GameManagerはゲームの進行を管理するために用意するゲームオブジェクトのことです。
ゲームの進行を管理する、とは例えば
- ゲーム開始ボタンをクリックしたらプレイヤーを動かせるようにする
- プレイヤーが死んだらゲームオーバー状態にして、ゲームを停止させる
- スコアを記録する
といったことですね。こういった処理をバラバラのゲームオブジェクトで行うととても面倒なことになってしまうので、単一のゲームオブジェクトに任せようというのが主なポイントです。
ちなみにGameManagerはUnityの機能とかではなく、単に「そういう役割のゲームオブジェクトを用意したらゲームを作りやすくなるよね」という概念のことを指すので勘違いしないようにしてください。
GameManagerのC#スクリプト
では早速ですがGameManagerのC#スクリプトを書いていきましょう。新しいC#スクリプトを作り、名前を「GameManager」に変更したら次のコードを書いてください。
using UnityEngine; public class GameManager : MonoBehaviour { [SerializeField] PlayerController player = null; [SerializeField] MeteorSpawner[] spawners = null; [SerializeField] Canvas gameStartCanvas = null; [SerializeField] Canvas gameOverCanvas = null; void Start() { player.gameObject.SetActive(false); SetActiveSpawners(false); // タイトル画面を表示 gameStartCanvas.gameObject.SetActive(true); } public void GameStart() { // タイトル画面やゲームオーバー画面を非表示 gameStartCanvas.gameObject.SetActive(false); gameOverCanvas.gameObject.SetActive(false); // 画面上に残っている隕石を削除 GameObject[] meteors = GameObject.FindGameObjectsWithTag("Enemy"); foreach (GameObject meteor in meteors) { Destroy(meteor); } // プレイヤーの座標を原点に戻し、アクティブ状態にする player.transform.position = Vector3.zero; player.gameObject.SetActive(true); // スポナーを起動 SetActiveSpawners(true); } public void GameOver() { // ゲームオーバー画面の表示 gameOverCanvas.gameObject.SetActive(true); // スポナーを停止 SetActiveSpawners(false); } void SetActiveSpawners(bool value) { foreach(MeteorSpawner spawner in spawners) { spawner.isActive = value; } } }
書けたらこれを空のゲームオブジェクトにアタッチしましょう。
GameManagerオブジェクトの設定を行う
次にGameManagerの設定を行います。インスペクタで先ほどのゲームオブジェクトを開き、Game Managerコンポーネントの各空欄に
- Player
- Spawner
- タイトル画面のキャンバス
- ゲームオーバー画面のキャンバス
を残らず設定してください。まだSpawnerをシーンに配置していない場合は適当に配置してから設定を行いましょう。
ボタンにGameManagerスクリプトの関数を登録する
そうしたら、このままではタイトル画面等のボタンをクリックしても何も起きないので、ボタンにGameManagerスクリプトの関数を登録します。下の画像のように2つのボタンにそれぞれ「GameStart」関数を設定してください。
プレイヤーのC#スクリプトの変更
これでゲームを開始することができるようになりましたが、まだ自機にゲームオーバー処理を追加していないので隕石にぶつかっても何も起きません。そこでプレイヤーのC#スクリプトに少しだけコードを追加して、隕石にぶつかったらゲームオーバー処理を呼び出せるようにします。
変更後のC#スクリプト
ではコードを追加した後のプレイヤーのC#スクリプトを掲載します。関係ない部分はバッサリ省略してあるのでご注意ください。
public class PlayerController : MonoBehaviour { public bool isActive = true; [Header("必要なコンポーネントを登録")] [SerializeField] Rigidbody2D rigidBody = null; [SerializeField] Transform bulletSpawn = null; [SerializeField] AudioSource audioSource = null; [SerializeField] GameManager gameManager = null; // ★追加 // -- 省略 -- // ★追加 void OnCollisionEnter2D(Collision2D collision) { if (collision.gameObject.CompareTag("Enemy")) { gameManager.GameOver(); gameObject.SetActive(false); } } }
変更できたら、プレイヤーのゲームオブジェクトをインスペクタで開いてGame Managerの欄にシーンのGameManagerオブジェクトを登録しましょう。
テストプレイして動作を確認しよう
ここまでできたら、最後にテストプレイして動作を確認しておきます。Unityの再生ボタンを押してみて
- 最初にタイトル画面が表示される
- 「Start」ボタンを押すとゲームが始まって隕石が迫ってくる
- 隕石に衝突するとゲームオーバー画面が表示される
- 「Retry」ボタンを押すと再度ゲームが始まる
という風になれば成功です。
次のページ→自機や敵に爆発エフェクトをつける方法