
Unityのステートマシン(ステートマシン)の別の実施形態を共有したいと思います。 UnityやC#と組み合わせた有限状態マシンに関する記事はすでにHabréに掲載されています。たとえば、
ここにありますが、Unityコンポーネントの使用に基づいて少し異なるアプローチを示したいと思います。
記事のコードを
使用して
unitypackageにリンクし
ます 。
ステートマシンが何であるかまだわからない場合のどが渇いた定義については、ウィキペディアへのリンクを提供します。
状態マシン (ロシア語)
有限状態マシン (英語)
ゲームの例を使用して、簡単な言語で説明しようとします。
ステートマシンは、たとえばキャラクターの状態など、
一連の状態です。
現在の時点でアクティブにできるのは1つだけです。 つまり、示されたリストに従って、キャラクターは次のことができます。
- リラックスするか
- 走るか
- ジャンプするか
- どちらかの戦い
- 死んでいるか
そして、その間の遷移は 、たとえば次のような
所定の条件が満たされたときに実行されます 。
- レスト->モーションキーが押された場合に実行
- Rest->ジャンプキーが押されたらジャンプ
- 敵と衝突した場合は、実行->戦闘
- ファイト->体力がなくなったら死ぬ
- ...
明確にするために、上記の有限状態マシンをグラフ形式で想像してください。緑は状態マシンの初期状態、赤は最終状態です。

実装
ステートマシンの実装は、同じ名前のファイルにある
StateMachine 、
State 、
Transitionの3つのクラスで構成されます。 3つのクラスはすべて
MonoBehaviourから継承され
ます 。
StateMachineクラスは直接使用されますが、抽象
Stateおよび
Transitionから特定の状態および遷移を継承することが提案されています。 その結果、ステートマシン自体とそのすべての状態と遷移はコンポーネントであり、シーン内のオブジェクトに割り当てる必要があります。 さて、状態を切り替えるには、コンポーネントのオン/オフを切り替える既存のメカニズム(
enabledプロパティ)を
使用できます。 これにより、ステートマシン、オン/オフチェックなどに特化したコールバックを作成する必要がなくなります。 代わりに、通常のUnityイベント関数
OnEnable 、
OnDisable 、
Update 、
Awakeなどが使用されます。 確かに、2つの微妙な点があります。
- Startイベントには注意する必要があります。最初は、ステートマシンの状態と遷移を「オフ」にする必要があります。オフのコンポーネントの場合、このイベントはシーンの開始時ではなく、初めて「オン」になったときに発生します。 これがUnityの標準的な動作です。
- Stateから継承する場合、 FixedUpdateメソッドをオーバーライドする必要があります(もちろん必要な場合) 。Stateクラスに実装されているため、状態の「有効化/無効化」チェックボックスは常にインスペクターに表示されます。 このチェックマークを使用すると、状態の切り替えをリアルタイムで観察できます。ほとんどが「ビジュアルデバッグ」です。
最後に、コードに移りましょう(ロシア語のコメント付き):
都道府県 using UnityEngine; using System.Collections.Generic;
結果のステートマシンを使用する
画面上でキューブを左右に動かす小さなテストプロジェクトを作成しましょう。 プロジェクトは2Dと3Dの両方で作成できますが、違いは視覚的なものでなければなりません。 シーンを作成するか、デフォルトを使用します。 既にカメラが入っているので、メニュー
GameObject-> Create Other-> Cubeを使用してキューブを追加します。 キューブは、X軸上の位置を-4に設定する必要があります。これは、キューブが各方向に8単位移動するためです。 キューブに加えて、ステートマシン用に空の子オブジェクトを作成します。 これを行うには、階層でキューブを選択し、メニュー
GameObject-> Create Empty Childを使用します。 StateMachineに名前を変更すると、より明確になります。
判明します
次のステップは、スクリプトを作成することです。 4つのスクリプトが必要です。これはタイマー遷移クラスです。
タイマー遷移 using UnityEngine; using System.Collections;
状態用の3つのクラス。
Transformコンポーネントの
Translateメソッドを使用してオブジェクトを移動するモーション状態の基本クラス:
それから継承された特定の状態のクラス:
必要なクラスがすべて準備できたので、コンポーネントからステートマシンをアセンブルする必要があります。 これを行うには、階層でStateMachineという名前のオブジェクトを選択し、図のようにすべてのコンポーネントをその上にハングさせます。
状態と遷移のコンポーネントを「オフにする」ことを忘れないでください。状態マシン自体は忘れないでください。
次のようにコンポーネントを入力します。
状態と遷移用のフィールドは、対応するコンポーネントをドラッグアンドドロップすることで入力できます。 StartingStateステートマシンを設定し、遷移状態リストに遷移を追加することを忘れないでください!
これで、シーンを開始できます。 すべてが正しく行われると、キューブは画面を左右に移動します。 HierarchyでStateMachineオブジェクトを選択すると、インスペクターで状態遷移をリアルタイムで監視できます。
おわりに
結論として、このステートマシンの実装には欠点がないわけではありませんが、小規模なプロジェクトでの使用には非常に適しています。 私の意見では、より大規模なプロジェクトの場合、インスペクターでコンポーネントをドラッグアンドドロップするのはかなり不快な仕事です。
建設的な批判は大歓迎です。