🏷️

【Unity】バトル開始からリザルトまでの流れを作る

2020/12/18に公開

はじめに

タワーディフェンスを作ろうの記事第5回目です。
今回はゲーム開始からリザルトまでのゲームの流れを作っていきたいと思います。

今までの記事はこちら。
https://zenn.dev/supple/articles/2012a0ebfe13181286af
https://zenn.dev/supple/articles/64c9f9aaf2e7ca6f7151
https://zenn.dev/supple/articles/e4a5a7bb57922c
https://zenn.dev/supple/articles/884d2439cd034a

ゲームの流れを「状態」に分ける

どんなゲームにも流れというものがあります。
大体のゲームは始まる前にReadyGoの演出があり、決着が付いたら勝利演出、リザルトがあります。
この流れを作るのにあたり、まずは流れの中にどのような「状態」があるのかを洗い出します。

  • 戦闘開始演出
  • ゲーム中
  • 勝利演出
  • 敗北演出

状態の種類はざっくりこの4種類といったところでしょうか。
これらを一つの状態として定義し、別々に実行できるようにします。

状態を定義する

それぞれの状態をenumで定義します。
そして、現在の状態を表すパラメーターを追加します。

BattleManager.cs
    // ゲームの状態
    public enum GameState
    {
        BattleStart,    // バトル開始演出中
        BattleMain,     // バトル中
        Win,            // 勝利演出中
        Lose,           // 敗北演出中
    }
    // 現在のゲームの状態
    //  最初はバトル開始演出中の状態にしておく。
    GameState currentState = GameState.BattleStart;

状態ごとに処理を分離する

Updateで現在の状態を見て、呼び出すメソッドを変えてあげます。
こうすることによって、他の状態に影響を与えずにそれぞれの状態の処理を行えるようになります。

BattleManager.cs
    private void Update()
    {
        // 現在のゲームの状態によって呼び出す処理を変える
        switch(currentState)
        {
            case GameState.BattleStart: // バトル開始演出中の時
                BattleStartUpdate();    // バトル開始中の更新メソッドを呼ぶ
                break;
            case GameState.BattleMain:  // バトル中のとき
                BattleMainUpdate();     // バトル中の更新メソッドを呼ぶ
                break;
            case GameState.Win:         // 勝利演出中のとき
                WinUpdate();            // 勝利演出中の更新メソッドを呼ぶ
                break;
            case GameState.Lose:        // 敗北演出中のとき
                LoseUpdate();           // 敗北演出中の更新メソッドを呼ぶ
                break;
        }
    }

バトル開始演出

バトル開始演出中の状態はゲームが始まって最初の状態です。
演出が終わったらcurrentStateを変更してバトル中に移行します。
今回は何もせず、すぐにバトルに移行します。

BattleManager.cs
    // 現在のゲームの状態がバトル開始中の時の更新を行う
    void BattleStartUpdate()
    {
        // TODO:バトル開始演出を行う。    
        // 演出が終わったらゲームの状態をバトル中に変更する
        currentState = GameState.BattleMain;
    }

バトル中

バトル中の状態の時には、今までUpdateで行っていた事をこのメソッドの中に移動します。
こうする事で他の状態でバトルが動いてしまわないようにします。
敵のユニットが全滅したら状態をWinに、プレイヤーのユニットが全滅したら状態をLoseに変えてリザルトに移行します。

BattleManager.cs
    // 現在のゲームの状態がバトル中の時の更新を行う
    void BattleMainUpdate()
    {
        // 全てのユニットを更新する
        foreach (Unit unit in sortieUnits)
        {
            unit.UpdateUnit(Time.deltaTime);
        }

        if(!sortieUnits.Exists((unit) => unit.group == Unit.GroupType.Enemy))
        {   // 敵のユニットが一つも見つからなければ勝利する
            currentState = GameState.Win;   // ゲームの状態を勝利演出中に変更する
        }
        else if(!sortieUnits.Exists((unit) => unit.group == Unit.GroupType.Player))
        {   // プレイヤーのユニットが一つも見つからなければ敗北する
            currentState = GameState.Lose;  // ゲームの状態を敗北演出中に変更する
        }
    }

勝利、敗北演出

バトルの決着が付いたらリザルトを表示します。
演出終了後何かキーが押されたら、勝利した場合は次のステージのシーンを、敗北した場合はタイトルのシーンをロードします。

BattleManager.cs
    // 次ステージのシーン名
    public string nextStageSceneName;
    
    /// 現在のゲームの状態が勝利演出中の時の更新を行う
    void WinUpdate()
    {
        // TODO:勝利演出を行う
	
        if(Input.anyKeyDown)
        {   // 何かキーが押されたら
            // 次ステージのシーンをロードする
            SceneManager.LoadScene(nextStageSceneName);
        }
    }

    // 現在のゲームの状態が敗北演出中の時の更新を行う
    void LoseUpdate()
    {
        // TODO:敗北演出を行う
	
        if(Input.anyKeyDown)
        {   // 何かキーが押されたら
            // タイトルシーンに戻る
            SceneManager.LoadScene("Title");
        }
    }

最後に

最近の記事の内容が初心者離れして来ているのを反省して
初心に戻って状態の管理について一番簡単な方法を紹介させてもらいました。
友人にアイコン素材を作ってもらったので次回はUIを作っていきたいと思います。

Discussion