原カバンは鞄のお店ではありません。

Unityを使ったゲーム制作のあれこれを綴っていきます。

【Unity】公式サンプルプロジェクトから学ぶデザインパターン:State

階段

なぜか下り階段の一番最後の段が苦手な皆さんこんにちは。階段を降りる時、それまでは同じペースで歩を進めていたのに一番最後の段になると何故か急に距離感が掴めなくなって踏み外しそうになります。階段にトラウマとかないはずですが原因が分かりません。ちょと怖いです。

 

デザインパターン

さて、Unity公式から公開されているデザインパターン学習用のサンプルプロジェクトについての記事6回目

github.com

これまでは以下のデザインパターンについて記事を書いてます。

www.karvan1230.com

www.karvan1230.com

www.karvan1230.com

www.karvan1230.com

www.karvan1230.com

 

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」クラスのような管理クラスを作成して「状態」の入れ替えを行うのが一般的です。
「状態」の遷移判定は各状態クラスの内部で行っても、外部クラスで行っても構いませんが、遷移条件はきちんと整理する必要があります。

 

◇プライバシーポリシー

●個人情報の利用目的

当ブログでは、メールでのお問い合わせ、メールマガジンへの登録などの際に、名前(ハンドルネーム)、メールアドレス等の個人情報をご登録いただく場合がございます。

これらの個人情報は質問に対する回答や必要な情報を電子メールなどをでご連絡する場合に利用させていただくものであり、個人情報をご提供いただく際の目的以外では利用いたしません。

●個人情報の第三者への開示

当サイトでは、個人情報は適切に管理し、以下に該当する場合を除いて第三者に開示することはありません。

・本人のご了解がある場合
・法令等への協力のため、開示が必要となる場合

個人情報の開示、訂正、追加、削除、利用停止
ご本人からの個人データの開示、訂正、追加、削除、利用停止のご希望の場合には、ご本人であることを確認させていただいた上、速やかに対応させていただきます。

アクセス解析ツールについて

当サイトでは、Googleによるアクセス解析ツール「Googleアナリティクス」を利用しています。

このGoogleアナリティクスはトラフィックデータの収集のためにCookieを使用しています。このトラフィックデータは匿名で収集されており、個人を特定するものではありません。
この機能はCookieを無効にすることで収集を拒否することが出来ますので、お使いのブラウザの設定をご確認ください。

●免責事項

当サイトからリンクやバナーなどによって他のサイトに移動された場合、移動先サイトで提供される情報、サービス等について一切の責任を負いません。

当サイトのコンテンツ・情報につきまして、可能な限り正確な情報を掲載するよう努めておりますが、誤情報が入り込んだり、情報が古くなっていることもございます。

当サイトに掲載された内容によって生じた損害等の一切の責任を負いかねますのでご了承ください。

●プライバシーポリシーの変更について

当サイトは、個人情報に関して適用される日本の法令を遵守するとともに、本ポリシーの内容を適宜見直しその改善に努めます。

修正された最新のプライバシーポリシーは常に本ページにて開示されます。