結果画面を作ったら、Retryが思ったより簡単じゃなかった話
はじめに
前回の記事では、
勝敗表示(WIN / LOSE)を出すところまで実装しました。
そのあと少し間が空いてしまいました。
最近は会社がかなり忙しく、泊まり込みになる日もあったりして、
Unityを触る時間があまり取れませんでした。
久しぶりにUnityを開いたとき、
まず「前回どこまでやったんだっけ?」と思い出すところから始まりました。
今回はその続きとして、
結果画面とRetryボタン まわりを触ってみました。
結果画面(ResultPanel)を作る
前回は、勝ったときや負けたときに
TextMeshProで「WIN」や「LOSE」と表示するだけでした。
でもそれだと、
- 表示されたあともプレイヤーは動ける
- ゲームが終わった感じがしない
- 次にどうすればいいのか分からない
という状態でした。
そこで、
- WIN / LOSE の文字
- Retry ボタン
- Title ボタン
をまとめた ResultPanel を作ることにしました。
Hierarchy はこんな感じにしました。
Canvas
└ ResultPanel
├ ResultText
├ RetryButton
└ TitleButton
最初は ResultPanel を非表示にしておいて、
勝敗が決まったときにまとめて表示するようにしました。
Win / Lose のときにPanelを表示する
GameManager の Win / Lose の中で、
ResultPanel を表示するようにしました。
if (resultPanel != null)
resultPanel.SetActive(true);
これで、
- ゲーム中 → Panel 非表示
- 勝った / 負けた → Panel 表示
という流れになりました。
ここまでで、
「ゲームが終わって結果画面が出る」
という形が少しゲームっぽくなってきました。
ボタンを押したら処理が動くようにする
次に、RetryButton と TitleButton を作って、
ボタンを押したときに GameManager の関数が呼ばれるようにしました。
Unity の Button の OnClick() から、
- RetryButton → OnRetryClicked()
- TitleButton → OnTitleClicked()
を呼ぶように設定しました。
最初はボタンを押したら Console にログを出すだけにしました。
public void OnRetryClicked()
{
Debug.Log("Retry clicked");
}
ここで初めて、
「ボタン → スクリプトの関数」
というつながりを作ることができました。
Retryを作り始めて気づいたこと
次に、Retry ボタンを押したら
もう一回ゲームができるようにしようと思いました。
まずは ResultPanel を閉じるところから始めました。
public void ResetGame()
{
ended = false;
if (resultPanel != null)
resultPanel.SetActive(false);
if (resultText != null)
resultText.text = "";
}
そして RetryButton を押したときに
この ResetGame() を呼ぶようにしました。
これで、
- 結果画面が消える
- ゲーム終了状態が解除される
ところまではできました。
でも、これだけでは足りなかった
実際に動かしてみると、
Retry を押しても完全に最初に戻っていないことに気づきました。
例えば、
- 敵は復活していない
- 敵のHPは0のまま
- プレイヤーの位置もそのまま
という状態でした。
そこで、Enemy をもう一度表示するようにしました。
if (enemyObject != null)
enemyObject.SetActive(true);
これで敵はもう一度表示されるようになりました。
でも今度は、
- 敵のHPは0のまま
- プレイヤーのHPも戻っていない
- プレイヤーの位置も戻っていない
という問題が残りました。
「Retry = 最初に戻る」って思ったより重い
ここで初めて気づいたのは、
Retryって、ただ画面を戻すだけじゃなくて、
ゲームの状態を全部最初に戻す必要がある
ということでした。
戻さないといけないものを考えてみると、
- ゲーム終了状態
- ResultPanel
- ResultText
- Enemyの表示状態
- EnemyのHP
- PlayerのHP
- Playerの位置
- Enemyの位置
など、思ったよりたくさんありました。
最初は、
Retryボタンを押したら、なんとなく最初に戻る
くらいのイメージでしたが、
実際には「何を戻すのか」を一つ一つ考えないといけないと分かりました。
今回少しだけ分かったこと
今回やってみて思ったのは、
- UIを出すだけなら比較的簡単
- でも「ゲームの状態を戻す」のは意外と難しい
- ゲームは見た目だけじゃなく、内部の状態がたくさんある
ということでした。
Retryを作り始めただけなのに、
「ゲームの中で何を管理しているのか」を
少し考えるようになりました。
まだ完全に理解できているわけではありませんが、
少なくとも
Retry = 画面を戻すだけではない
ということは分かりました。
次にやりたいこと
次は、
- EnemyのHPを初期値に戻す
- PlayerのHPを初期値に戻す
- PlayerとEnemyの位置を初期位置に戻す
など、本当の意味で「最初からやり直し」ができる
Retryを作ってみたいと思います。
少しずつですが、
ゲームの「中身」に近づいている気がします。