前回、クリア・ゲームオーバー表示用のキャンバスを作成しました。今回はゲーム進行を担う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」にしてください。

