ブロック崩しゲームで状態管理を作成する第4回目です。今回で目的とした「状態管理」を中心としたゲーム作成は一旦完成です。
はじめに
今回は第4回目です。第1回目は下記から。
前回までのおさらい、今回やる事
前回までで「メニュー」、「ゲーム」、「終了」のある程度の流れを作成しました。今回は次ステージへの移動、終了からメニューへ移動、初期化や細かい修正を行い一旦、完成させます。

複数ステージ・状態の追加
現状だとステージが一つしかないので、「ステージクリア」=「ゲームクリア」です。これを「複数ステージ」にして、ステージクリアで次のステージ。次のステージがなければゲームクリアに変更します。
複数ステージの作成
まずは適当にStage1プレハブを複製してStage2を作成。どんな形でもOK。

次にGameManagerのスクリプトに「STAGECLEAR」と「LOADSTAGE」の状態を追加。初めは一つの予定でしたが、作成していくうちに2つあった方がやりやすかったので2つ追加しました。

public enum Status { MENU, GAME, STAGECLEAR, LOADSTAGE, FINISH }
ステージのプレハブを配列に変更し、アクティブなステージの番号を保管しておく変数も追加します。


public GameObject[] stagePrefab; int _stageNo;
ステージを保管する変数を配列に変更したのでステージを追加。

次に、ステージクリア時に表示するパネルを追加。メニューパネルをコピーしてテキストを変更。

NEXT STAGEボタンを押した時に次のステージへ行く関数を作成。
public void NextStageClick() { panelStageClear.SetActive(false); ChangeStatus(Status.LOADSTAGE); }
ステージクリア時、ボールとバーが残るので、これをブロックと同じようにプレハブ化。

スクリプトを変更。それぞれの状態では下記のように。

他にも、変更していますが、スクリプトが長くなるので最終的な完成スクリプトを下に掲載します。
初期化追加
初期化の状態を追加。初期化は大体どのゲームでもあったほうがよいものですね。簡単なものだと無しでも出来なくはないですが。

最終的なGameManegerのスクリプトは下記
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; public class GameManager : MonoBehaviour { public GameObject ballPrefab; public GameObject playerPrefab; public GameObject[] stagePrefab; public GameObject panelMenu; public GameObject panelFinish; public GameObject panelStageClear; public Text finishText; public static GameManager instance { get; private set; } public int Balls; public enum Status { MENU, INIT, GAME, STAGECLEAR, LOADSTAGE, FINISH } Status _status; GameObject _stage; GameObject _ball; GameObject _player; int _stageNo; void Start() { instance = this; _stageNo = 0; ChangeStatus(Status.MENU); } void Update() { switch (_status) { case Status.GAME: if(_ball == null) { if (Balls > 0) { _ball = Instantiate(ballPrefab); } else { finishText.text = "GAME OVER"; ChangeStatus(Status.FINISH); } } if (_stage !=null && _stage.transform.childCount == 0) { ChangeStatus(Status.STAGECLEAR); } break; case Status.FINISH: if(Input.anyKeyDown) { panelFinish.SetActive(false); Destroy(_player); Destroy(_stage); _stageNo = 0; ChangeStatus(Status.MENU); } break; default: break; } } public void StartClick() { panelMenu.SetActive(false); ChangeStatus(Status.INIT); } public void NextStageClick() { panelStageClear.SetActive(false); ChangeStatus(Status.LOADSTAGE); } void ChangeStatus(Status nextstatus) { _status = nextstatus; switch (nextstatus) { case Status.MENU: panelMenu.SetActive(true); break; case Status.INIT: Balls = 1; _player = Instantiate(playerPrefab); ChangeStatus(Status.LOADSTAGE); break; case Status.GAME: break; case Status.STAGECLEAR: Destroy(_ball); Destroy(_stage); _stageNo++; if (_stageNo >= stagePrefab.Length) { finishText.text = "GAME CLEAR"; ChangeStatus(Status.FINISH); } else { panelStageClear.SetActive(true); } break; case Status.LOADSTAGE: _stage = Instantiate(stagePrefab[_stageNo]); ChangeStatus(Status.GAME); break; case Status.FINISH: panelFinish.SetActive(true); break; } } }
ゲームの流れとしては下記のようなイメージ。

とりあえず一連のゲームの流れは完成。もちろん、足りない部分は多いけど、今回の目的の「状態管理」は大体できたかなと。
GameManagerスクリプトにあえて全部入れたけど、見る人の事を考えたら分けた方が良かったですな。