
階段
なぜか下り階段の一番最後の段が苦手な皆さんこんにちは。階段を降りる時、それまでは同じペースで歩を進めていたのに一番最後の段になると何故か急に距離感が掴めなくなって踏み外しそうになります。階段にトラウマとかないはずですが原因が分かりません。ちょと怖いです。
デザインパターン
さて、Unity公式から公開されているデザインパターン学習用のサンプルプロジェクトについての記事6回目
これまでは以下のデザインパターンについて記事を書いてます。
Stateパターン
Stateパターンはオブジェクトの振る舞いに関するデザインパターンの一つです。
オブジェクトの「振る舞い」が状況によらず一様に同じである場合は特に考慮する必要はありませんが、外部や内部の影響によりオブジェクトの「状態」が変わり、それによって「振る舞い」が変わる場合ではどうでしょう?
例えば、「Woman」というクラスは同じ言葉で同じように依頼をお願いしたとしても、その時の「状態」により応答が異るとした場合、その後の対応は「Woman」の応答に応じて処理を行う必要があります。

この場合、まずは「Woman」の現在の状態を条件付き演算子 (if または switch) で判定し、その条件分岐毎に応答するレスポンスを決定する形になりますが、そうすると、その後に新しい「状態」を追加したい場合は、全ての条件付き演算子の分岐を見直さなければならないような設計となってしまいます。
このようなケースでコードの冗長化を防ぎ、保守性を高める設計思想がStateパターンです。
Stateパターンでは「状態」をクラスとして表現し、この「状態」を入れ替え可能にしておくことで、条件付き演算子による分岐を無くし、処理を単純明快にして、新しい「状態」の追加にも対応することができます。
サンプルシーン
サンプルプロジェクトの「10 State」ディレクトリ配下にあるサンプルシーンは以下のよう動作をします。

シリンダー形状の自機は動かしていない場合は「Idle」状態、動き出すと「Walk」状態、スペースキーでジャンプすると「Jump」状態に遷移します。現在の状態は自機の上にテキスト表示されており確認することができます。
このサンプルシーンでは各状態を同じインターフェイス(IState)を継承したクラス(State)で実装しており、IStateインターフェイスでは以下のメソッドを定義しています。
- Enter:その状態に遷移した時に呼ばれる
- Update:その状態中に毎フレーム呼ばれる
- Exit:その状態から他の状態に遷移する時に呼ばれる
自機の現在の状態(State)は「StateMachine」クラスにより管理されています。
「StateMachine」クラスは「Idle」「Walk」「Jump」それぞれのStateクラスを入れ替えて「現在のStateクラス」を把握しており、「現在のStateクラス」に対してIStateインターフェイスで定義されている各メソッドの呼び出しを行います。
Stateの遷移は各状態クラスの中で行っており、現在の状態が他のStateへ遷移する条件と合致すると「StateMachine」クラスに対して他Stateへの遷移を依頼、「StateMachine」クラスは依頼されたStateを「現在のStateクラス」として入れ替えます。
各クラスの関係を図で表現するとこんな感じになります。

まとめ
Stateパターンはオブジェクトの各状態をそれに対応した各クラスで表現するパターンです。
このパターンを適用すると、各状態を個々のクラスで表現するため、処理が単純明快となります。
「StateMachine」クラスのような管理クラスを作成して「状態」の入れ替えを行うのが一般的です。
「状態」の遷移判定は各状態クラスの内部で行っても、外部クラスで行っても構いませんが、遷移条件はきちんと整理する必要があります。