前回、クリア・ゲームオーバー表示用のキャンバスを作成しました。今回はゲーム進行を担うGameManagerのC#スクリプトを変更して、実際にクリアやゲームオーバーの表示が出るようにしていきます。
- 今回の内容だけではエラーが出てしまうので、次のPart2の作業も併せて進めるようにしてください。
- 初級コースにしてはやや難しめの内容ですが頑張りましょう。
変更後のGameManager.csのC#スクリプト
では早速ですがGameManager.csを次のように書き換えてください。
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; [RequireComponent(typeof(MoveSceneManager))] [RequireComponent(typeof(SaveManager))] [RequireComponent(typeof(SoundManager))] [DefaultExecutionOrder(-5)] public class GameManager : SingletonMonoBehaviour<GameManager> { [Header("シーンロード時に自動生成するプレハブを登録")] [SerializeField] GameObject[] prefabs = null; [SerializeField] AudioClip bgm = null; [SerializeField] AudioClip clearSe = null; [SerializeField] AudioClip gameOverSe = null; [SerializeField] string stageTextName = "StageText"; [SerializeField] GameObject clearCanvasPrefab = null; [SerializeField] GameObject gameOverCanvasPrefab = null; [SerializeField] string nextButtonName = "NextButton"; [SerializeField] string retryButtonName = "RetryButton"; [SerializeField] string titleButtonName = "TitleButton"; bool isClear = false; bool isGameOver = false; Text stageText; MoveSceneManager moveSceneManager; SaveManager saveManager; SoundManager soundManager; PlayerController player; protected override void Awake() { base.Awake(); if (Debug.isDebugBuild) { } moveSceneManager = GetComponent<MoveSceneManager>(); saveManager = GetComponent<SaveManager>(); soundManager = GetComponent<SoundManager>(); } void Start() { if (Debug.isDebugBuild) { InstantiateWhenLoadScene(); ExecWhenLoadScene(); } if (bgm != null) { soundManager.PlayBgmByName(bgm.name); } } void InitGame() { isClear = false; isGameOver = false; } public void Clear() { if (isClear) { return; } isClear = true; player.DestroyPlayer(); if (clearSe != null) { soundManager.PlaySeByName(clearSe.name); } //次のステージのフラグが立っていなければ立ててセーブ if (moveSceneManager.CurrentSceneNum < moveSceneManager.NumOfScene - 1) { bool flag = saveManager.GetFlag(moveSceneManager.CurrentSceneNum + 1); if (!flag) { saveManager.SetFlag(moveSceneManager.CurrentSceneNum + 1); saveManager.Save(); } } //クリア時のキャンバスを表示 Instantiate(clearCanvasPrefab); Button nextButton = GameObject.Find(nextButtonName).GetComponent<Button>(); Button titleButton = GameObject.Find(titleButtonName).GetComponent<Button>(); //キャンバスのボタンにイベントを登録 if (moveSceneManager.CurrentSceneNum >= moveSceneManager.NumOfScene - 1) { //最終ステージなら「次のステージ」ボタンを無効化 nextButton.interactable = false; } else { nextButton.onClick.AddListener(() => moveSceneManager.MoveToScene(moveSceneManager.CurrentSceneNum + 1)); } titleButton.onClick.AddListener(() => moveSceneManager.MoveToScene(0)); } public void GameOver() { if (isGameOver) { return; } isGameOver = true; player.DestroyPlayer(); if (gameOverSe != null) { soundManager.PlaySeByName(gameOverSe.name); } //ゲームオーバー時のキャンバスを表示 Instantiate(gameOverCanvasPrefab); Button retryButton = GameObject.Find(retryButtonName).GetComponent<Button>(); Button titleButton = GameObject.Find(titleButtonName).GetComponent<Button>(); //ボタンにイベントを登録 retryButton.onClick.AddListener(Retry); titleButton.onClick.AddListener(() => moveSceneManager.MoveToScene(0)); } void Retry() { moveSceneManager.MoveToScene(moveSceneManager.CurrentSceneNum); } //シーンが読み込まれたときに登録したプレハブをInstantiateするメソッド public void InstantiateWhenLoadScene() { if (moveSceneManager.SceneName == "Title") { return; } foreach (GameObject prefab in prefabs) { Instantiate(prefab, transform.position, Quaternion.identity); } } //シーンが読み込まれたときに実行するメソッド public void ExecWhenLoadScene() { if (moveSceneManager.SceneName == "Title") { return; } LoadComponents(); InitGame(); UpdateStageUi(); } void LoadComponents() { player = GameObject.FindGameObjectWithTag("Player").GetComponent<PlayerController>(); stageText = GameObject.Find(stageTextName).GetComponent<Text>(); } public void UpdateStageUi() { stageText.text = "ステージ" + moveSceneManager.CurrentSceneNum.ToString(); } }
C#スクリプトの解説
少し長めのスクリプトで、特にクリア時やゲームオーバー時の処理がややこしくなっています。
このスクリプトでやっていることは主に次の3つです。
- シーン読み込み時のセットアップ
(変数の初期化、メインキャンバス等の生成、必要なコンポーネントの取得など) - ゴールに触った時のクリア処理(PlayerControllerから呼ばれる)
…クリア用キャンバスの表示やセーブ処理 - 敵に触った時のゲームオーバー処理(PlayerControllerから呼ばれる)
…ゲームオーバー用キャンバスの表示
C#スクリプトの流れ
シーンロード時
MoveSceneManager(※注)から次の2つのメソッドが呼ばれます(※タイトル画面を除く)。
- InstantiateWhenLoadScene()
- ExecWhenLoadScene()
ただし、今のところはExecWhenLoadSceneメソッドはMoveSceneManagerから呼ぶようにしていないので、あとで処理を追加する必要があります。
※注:MoveSceneManagerとは、「くろくま基本アセット」に含まれるシーンの移動を担うスクリプトのことです。
クリア時
登録されていれば効果音を鳴らし、セーブを行ってからクリア用キャンバスを表示します。
ただしクリア用キャンバスは動的に生成するため、ボタンには何もイベントが登録されておらず、そのままでは押しても何も起こりません。そこでAddListenerメソッドを使って、MoveSceneManagerのシーン移動用メソッドを登録します。
ゲームオーバー時
登録されていれば効果音を鳴らし、ゲームオーバー用キャンバスを表示します。
GameManagerコンポーネントの設定
スクリプトを変更できたら、GameManagerオブジェクトのGameManagerコンポーネントを次のように設定しましょう。
BGMや効果音をつけたい場合はネットから適当な素材を探してインポート・登録してください。なお、サウンド素材のインポートの場所は「Resources」→「Audio」→「BGM」または「SE」にしてください。