はじめに


ArborHeader

「Arbor: State Diagram Editor」について

  • Unityで有限ステートマシンを使ってゲーム作りたい!
  • だけど、ゲームロジックに依存する挙動は自分でコーディングしたい!
  • そんな時に使えそうな有限ステートマシンの編集ウィンドウと、
    作りたい挙動にあわせてステートのスクリプトを書けるシンプルなステートマシンアセットです。

そもそも有限ステートマシン(FSM)って何?

  • 有限ステートマシンとは、ある状態での挙動と、その状態から別の状態へ遷移する仕組みです。
  • たとえば、スイッチと電灯。
  • スイッチと電灯にはONとOFFという状態があり、スイッチをONにすれば電灯もONになります。
  • スイッチは押せばONに切り替わり、再度押すとOFFに切り替わる挙動です。
  • 電灯はONであれば明かりを灯す挙動になります。

ゲームでの使いどころ

ゲームの多くは、状態と挙動の移り変わりで表現できてしまうかと思います。
たとえば敵の動きなどは以下のようにすることがあります。

  • 「発生ステート」。
    敵が発生したら発生モーションをとる。
    モーション終了後、「パトロールステート」に遷移。
  • 「パトロールステート」。
    適当に巡回させつつどうしようか考える。
    プレイヤーが近くにいるとき、敵自身のHP高い場合は「追跡ステート」に遷移。
    HP低い場合は「逃走ステート」に遷移。
  • 「追跡ステート」。
    プレイヤーに攻撃できる位置まで移動する。
    攻撃できる位置に到着後、「攻撃ステート」に遷移。
  • 「攻撃ステート」。
    攻撃!
    攻撃モーション終了後、「パトロールステート」に戻る。
  • 「逃走ステート」。
    見つかったプレイヤーから逃げる。
    遠くまで離れたら安心して「パトロールステート」に戻る。

この例では、追跡するか逃亡するかを自分のHPで分岐しています。
たった1箇所での分岐ですが、文章にしてみるとどこでどう繋がっているかすぐには分かりませんね。
ラスボスのような複雑な動きをする場合は状態も挙動も複雑化して、さらに複数のステートマシンが連動する可能性もありえます。
ある時はパトロール、ある時は逃亡、という挙動を細かくスクリプトに、
あとはエディタで遷移の関係を編集する形にしたほうが視覚性が良くなり開発効率も向上するかと思います。

Arborを使えば、このように視覚的に状態の遷移を組むことができます。

Arbor_SS24

Arborを入手する

使い方

ArborFSMの追加

  • 適用したいGameObjectを選択
  • 「メニュー > Component > Arbor > ArborFSM」を選択 。
    ArborFSMの追加
  • あるいはInspectorの「Add Componentボタン > Arbor > ArborFSM」を選択。
    ArborFSMの追加(Add Componentから)
  • また、HierarchyのCreateボタン「Arbor > ArborFSM」からArborFSMがアタッチされた状態のGameObjectが作成できる。
    HierarchyのCreateボタンから作成

Arbor Editorを開く

  • 編集したいArborFSMのOpen Editorボタンをクリック。
    Arbor Editorを開く(Open Editorボタンから)
    あるいは「メニュー > Window > Arbor Editor」を選択

ArborFSMの選択

  • Arbor Editor上部の選択ボックスにドラッグ&ドロップ。
    あるいは選択ボックスをクリックしてリストから選択。
    ArborFSMの選択
  • ArborFSMのInspectorでOpen Editorボタンを押した場合は自動的に選択状態になる。

ステートの作成

  • Arbor Editorの適当な位置を右クリック。
  • 「ステート作成」をクリック。
    Stateの作成

ステートの名前変更

  • ステート枠内上部のテキストボックスを変更
    Stateの名前変更

開始ステートの指定

開始ステートとは、オブジェクトがアクティブになった際、一番初めに実行されるステートです。
開始ステートがない状態でステートを作成すると自動的に開始ステートになります。

  • ステート名横の設定アイコンをクリック。
    Stateの設定開く
  • 「開始ステートに設定」をクリック。
    開始ステートの指定

ステートの削除

  • ステートをクリックし選択。
  • 右クリックし、「削除」をクリック。
    ステートの削除

ステートに挙動を追加

  • ステート名横の設定アイコンをクリック。
    Stateの設定開く
  • 「挙動追加」を選択。
    ステートに挙動を追加1
  • 挙動一覧から追加したい挙動を選択。
    ステートに挙動を追加2
    (Free版、Lite版は組み込み挙動は同梱されていないため、スクリプトを自作する必要がある。)
  • 設定したいスクリプトファイルを直接ドラッグ&ドロップでも可。

挙動の削除

  • 挙動名横の設定アイコンをクリック。
    挙動の設定
  • 「削除」をクリック。
    挙動の削除

遷移に関する挙動(通常版のみ)

遷移に関する挙動は初めからいくつか組み込まれています。

  • ステート名の横にある設定アイコンから「挙動追加」を選択。
    ステートに挙動を追加1
  • Transitionの中に各種遷移系の挙動が入っている。
    TransitionBehaviours
  • 時間で遷移するTimeTransitionなどがある。

挙動のマニュアルを開く(通常版のみ)

組み込み済みの挙動に関して、ヘルプアイコンをクリックすることでマニュアルページをブラウザで開きます。

  • 各種挙動のタイトルバー横にあるヘルプアイコンをクリックする
    挙動のマニュアルを開く

挙動からステートへ接続

  • TimeTransitionなど遷移系の挙動をあらかじめ追加しておく。
  • ステート接続エリアから他Stateにドラッグ&ドロップ。
    GIF
  • 何もないところで離せば解除
    GIF

常駐ステートについて

常駐ステートは常に動き続けるステートで、強制的に割り込ませたい処理待ち(コリジョンなど)をする際に利用します。
動き続ける代わりに他のステートからの遷移は受け付けない点に気を付けてください。

  • Arbor Editorの適当な位置を右クリック。
  • 「常駐ステート作成」をクリック。
    常駐ステート作成
  • 作成したステートは緑色の特殊なステートとなります。
    常駐ステート

パラメータコンテナ

  • 適用したいGameObjectを選択
  • 「メニュー > Component > Arbor > ParameterContainer」を選択 。
    あるいはInspectorの「Add Componentボタン > Arbor > ParameterContainer」を選択。
  • パラメータの追加。
    「Parameters」の右側の+ボタンから、追加する型を選択(Int/Float/Bool)。
    ParameterContainer2
  • 編集
    名前、値を選択し編集。
    ParameterContainer3
  • パラメータの削除。
    パラメータ右側の-ボタンをクリック。

ステートリスト

  • ツールバーの「ステートリスト」をクリックすることで開閉。
    ステートリストの開閉
  • 左側にステートの一覧が表示されるのでステートをクリックすると選択される。
    GIF
  • 検索バーから、名前で検索(一部一致)、挙動の型で検索(全一致)が可能。
    GIF

値の指定方法を選択する

  • 各プロパティのフィールド横に▼マークがついている場合、クリックすることで値の指定方法を選択できる。
    Flexibleタイプの選択2
  • 値の種類によって選択項目は異なり、主にあるのは以下の通り。
    • Constant
      固定値を指定する
    • Parameter
      パラメータを参照する
    • Random
      指定範囲の中からランダムに取得する。
    • Calculator
      演算ノードからの入力を受け付ける。

演算ノードについて(ver 2.0.0以降)

演算ノードにより、変数の入出力や演算がArbor Editor上でできるようになります。

演算ノードの作成

  • Arbor Editorの適当な位置を右クリック。
  • 「演算ノード作成」をクリック。
    演算ノードの作成
  • 作成したい演算ノードをリストから選択
    演算ノードの作成2

演算スロットの接続

  • 入力もしくは出力スロットをドラッグアンドドロップして接続する
    GIF

コーディング

C#、JavaScript、一応Booのスクリプトを作成して自作の挙動や演算処理を用意できます。

JavaScriptやBooを使用する場合

  1. Assets以下にPluginsフォルダがない場合、Pluginsフォルダを作成
  2. Pluginsフォルダの中にArborフォルダを作成
  3. Arbor/Internal/にあるScriptsフォルダを作成したArborフォルダの中に移動し、名前をInternalに変更。
  4. Arbor/Core/にあるScriptsフォルダを作成したArborフォルダの中に移動し、名前をCoreに変更。

StateBehaviourスクリプトファイルの作成

  • Projectウィンドウから作成したい場所で右クリック。
  • 右クリックメニューから、「Create > Arbor > StateBehaviour」からお好きな言語を選択。
  • ファイル名を入力して決定

ステートの接続

  • 作成したスクリプトにpublicもしくはSerializeField属性をつけたStateLinkを宣言する。
    宣言すれば自動的にArbor Editorで編集可能になる。

    using UnityEngine;
    using System.Collections;
    using Arbor;
    
    public class TestBehaviour : StateBehaviour {
    	public StateLink nextState;
    	// 略
    }
    

    スクリプトによるステートの接続追加

  • 遷移したいタイミングでTransitionを呼ぶ。

    Transition( nextState );
    

演算ノードからの入力

  • 作成したスクリプトにpublicもしくはSerializeField属性をつけたInputSlotIntやInputSlotFloatなどを宣言する。
    宣言すれば自動的にArbor Editorで編集可能になる。

    using UnityEngine;
    using Arbor;
    
    public class TestBehaviour : StateBehaviour
    {
    	public InputSlotInt slotInt;
    	// 略
    }
    

    %e6%bc%94%e7%ae%97%e3%83%8e%e3%83%bc%e3%83%89%e3%81%8b%e3%82%89%e3%81%ae%e5%85%a5%e5%8a%9b%e4%be%8b

  • 値を取得するにはGetValueメソッドを使用する。
    int data = 0;
    slotInt.GetValue(ref data);
    if (data == 10)
    {
    	Debug.Log("Test");
    }
    

演算ノードからの入力(Flexible)

  • 作成したスクリプトにpublicもしくはSerializeField属性をつけたFlexibleIntやFlexibleFloatなどを宣言する。
    using UnityEngine;
    using Arbor;
    
    public class TestBehaviour : StateBehaviour
    {
    	public FlexibleInt flexible;
    	// 以下略
    }
    

    %e6%bc%94%e7%ae%97%e3%83%8e%e3%83%bc%e3%83%89%e3%81%8b%e3%82%89%e3%81%ae%e5%85%a5%e5%8a%9b%e4%be%8bflexible
    ArborEditorウィンドウでCalculucatorを選択すれば演算ノードからの入力を受け付ける。

  • 値を取得するにはvalueプロパティを使用する。
    if (flexible.value == 10)
    {
    	Debug.Log("Test");
    }
    

演算ノードへの出力

  • 作成したスクリプトにpublicもしくはSerializeField属性をつけたOutputSlotIntやOutputSlotFloatなどを宣言する。
    (ジェネリッククラスのOutputSlot<T>はUnityの仕様上シリアライズされないため、かならず継承したクラスを使用してください)
    宣言すれば自動的にArbor Editorで編集可能になる。

    using UnityEngine;
    using Arbor;
    
    public class TestBehaviour : StateBehaviour
    {
    	public OutputSlotInt slotInt;
    	// 以下略
    }
    

    %e6%bc%94%e7%ae%97%e3%83%8e%e3%83%bc%e3%83%89%e3%81%b8%e3%81%ae%e5%87%ba%e5%8a%9b%e4%be%8b

  • 値を設定するにはSetValueメソッドを使用する。
    slotInt.SetValue(10);
    

エディタ拡張

  • Unityで使用可能なインスペクタ拡張やPropertyDrawerなどがStateBehaviourにも使用できる

注意点

  • MonoBehaviourのenabledは実行制御のためすでに内部で使用しているため、代替となるbehaviourEnabledを使用してください。

次のステップへ