背景
『ゲームの作り方』を一言で表すとすると、『全部コルーチンにする』か『スタック式のステートマシンにする』が思いつきます。前者は RPG ツクール的な作り方にすることで、後者は update パターンで頑張る方法です。後者の一例を大雑把に解説します。
FSM (finite state machine)
データの階層
Fsm は State のスタックを持っています:
Fsm の作成時にあらかじめ全ての State を挿入しておきます。ここでの State は、『タイトル画面』『通常画面』『戦闘画面』のような大きな状態を表します。
State は update, on_enter などのライフサイクル関数を持ちます:
どの State がアクティブであるかを Stack で管理します。これにより、 通常画面 > カットシーン再生状態 > アニメーション待機状態 のようなネストを表現できます。
状態遷移
State::update に応じて StateReturn を返却します:
状態遷移は StateCommand によって指示します:
また遷移後の State を即座に更新するか、次のフレームに更新するかを StateReturn で指定します。たとえばアニメーション再生の待機状態を抜けた時は、即座に次の State を更新したいです。
並列実行
アニメーションの再生システムなどは、複数の State をまたいで稼働して欲しいです。このようになゲーム状態のコンポーネントやシステムは Fsm とは独立したデータとして持ち、 State は薄くしています。
まとめ
僕の昔のゲームの FSM を大雑把にご紹介しました。 ECS をベースにしていたこともあり、 State 自体はほとんどただのタグに過ぎないというのがちょっと面白いかもしれません。
ステート管理、シーン管理は人によって管理方法が全く異なる分野だと思います。一言で『ゲーム開発』と言っても、持っているイメージが全然違うのが難しい所ですね。