最終更新: kenken2020 2024年01月03日(水) 18:40:45履歴
目次
参考:UnityのAnimation遷移はビヘイビアツリーで管理するのが便利かもしれない
- Animatorは「コーギーエンジン・ Corgi Engine」又は「トップダウンエンジン・TopDown Engine」を使う
- ビヘイビアツリーは「Arbor3」を使う
- GetComponentでアニメーターコンポーネントを取得し
- GetBoolなどでアニメーターのパラメーターを取得し
- SetBoolなどで、パラメーターコンテナに値を格納する
using System.Collections; using System.Collections.Generic; using UnityEngine; using Arbor; public class get_parameter_container : MonoBehaviour { // Start is called before the first frame update Animator animator; //アニメーターコンポーネントを取得用 ParameterContainer pracon_01; //Arborのパラメーターコンテナ用 void Start() { //アニメーターコンポーネントを取得 animator = GetComponent<Animator>(); pracon_01 =gameObject.GetComponent<ParameterContainer>(); } // Update is called once per frame void Update() { //アニメーターコンポーネントの各種パラメーターを取得する var idle = animator.GetBool("Idle"); var speed = animator.GetFloat("Speed"); var jump = animator.GetBool("Jumping"); var walk = animator.GetBool("Walking"); var run = animator.GetBool("Running"); var damage = animator.GetBool("Dmage"); var alive = animator.GetBool("Alive"); var x_speed = animator.GetFloat("xSpeed"); var y_speed = animator.GetFloat("ySpeed"); //Arbor3のパラメーターコンテナに代入していく pracon_01.SetBool("para_bool", idle); pracon_01.SetFloat("para_speed", speed); pracon_01.SetBool("para_jump", jump); pracon_01.SetBool("para_walk", walk); pracon_01.SetBool("para_run", run); pracon_01.SetBool("para_damage", damage); pracon_01.SetBool("para_alive", alive); pracon_01.SetFloat("para_xspeed", x_speed); pracon_01.SetFloat("para_yspeed", y_speed); } }
参考:ActionBehaviourスクリプトファイルの作成
基本的な流れ
基本的な流れ
- ActionBehaviourを継承したクラスを作成する
- OnExecute()メソッドをオーバーライドし、挙動を自分で定義する
- OnExecute()メソッドの最後にFinishExecute()を呼んでノードを終了する
- これやらないと永遠にそのアクションを実行し続けるので注意!毎フレーム攻撃とかになる
参考:Decoratorスクリプトファイルの作成
基本的な流れ
基本的な流れ
- Decoratorを継承したクラスを作る
- OnConditionCheck()メソッドをオーバーライドし、成功/失敗を表すtrue/falseを戻り値として返す
参考:Behavior Tree ワタシハ ビヘイビアツリー チョットデキル
参考:Unity + Arborで敵AIを作るならこれだけは覚えておけ!集〜ビヘイビアツリー編〜
基本的な考え方
制御文を実現するためのノード(Decoratorノード)
参考:Unity + Arborで敵AIを作るならこれだけは覚えておけ!集〜ビヘイビアツリー編〜
基本的な考え方
- ツリー状の構造によって、次に行う行動を決定する
- ビヘイビアツリー幹と葉っぱの2つから成り立つ
- 幹に当たるのが「コンポジットノード」
- 葉っぱに当たるのが「アクションノード」
- それぞれのノードは、実行結果の状態(Success / Failure / …)を判定し、その戻り値を親ノードに返す
- コンポジットノードの役割
- コンポジットノードの役割はそのノード以下の部分木(ブランチと呼ばれる)によって表現される挙動(サブタスク)を制御すること
- Arbor3だと「Selector」と「Sequencer」にあたる
- アクションノードの役割
- アクションは葉ノードとして書き、Behavior Tree 外に実装された具体的な関数を呼び
制御文を実現するためのノード(Decoratorノード)
- if文、while文、for文 を実現するためのノード
- アクションノードやコンポジットノードに取り付けて、条件判定を行う
- データフローとは?
- データフローとは、ノードの処理結果を他のノードに受け渡すためのデータの流れを言います。
- データの入出力スロットを接続するとデータフローを活用できます。
- 「ヒエラルキー」やインスペクターの「パラメーターコンテナ」から直接ノードにドラッグ&ドロップして値を設定出来る
公式ドキュメント
OutpotSlotIntなどの出力スロットを宣言することでデータ出力ができます。
値を流せるので、手動で値を入力しなくて良い(手入力が減ってミスが防げる)
スクリプト例
TestOutputSlotBehaviourスクリプトファイルを作成し、以下のコードを記述してください。
OutpotSlotIntなどの出力スロットを宣言することでデータ出力ができます。
値を流せるので、手動で値を入力しなくて良い(手入力が減ってミスが防げる)
スクリプト例
TestOutputSlotBehaviourスクリプトファイルを作成し、以下のコードを記述してください。
using UnityEngine; using Arbor; [AddComponentMenu("")] public class TestOutputSlotBehaviour : StateBehaviour { public OutputSlotInt outputSlot; public override void OnStateBegin() { outputSlot.SetValue(Random.Range(100, 200)); } }100〜200の値の間でランダムな値が出力される
FlexibleField関連クラスを使用すると、固定値の指定やパラメータ参照もしくはデータフローからの入力を切り替えて参照できます。
複数の参照方法を選択できますので柔軟に値が設定できます。
TestFlexibleFieldBehaviourスクリプトファイルを作成し、以下のコードを記述してください。
複数の参照方法を選択できますので柔軟に値が設定できます。
- メリット
- 他のOutput系ノードから値を引っ張ってこれる
- パラメータを直接参照できる
- そのまま直接値を入力可能
TestFlexibleFieldBehaviourスクリプトファイルを作成し、以下のコードを記述してください。
using UnityEngine; using Arbor; [AddComponentMenu("")] public class TestFlexibleFieldBehaviour : StateBehaviour { public FlexibleInt flexibleInt; public override void OnStateBegin() { Debug.Log("flexibleInt : " + flexibleInt.value); } }スクリプト内で実際の値を使用する際は、valueを使用する
flexibleInt.value
項目 | 内容 |
Constant | 定数値。値を設定するフィールドが表示される。 |
Parameter | パラメータを参照する。パラメータについては ParameterContainer を参照してください。 |
DataSlot | データの入力スロット。 |
Hierarchy | グラフの階層から参照する。 |
- Hierarchyの場合
- Self
- 自グラフを所有しているGameObjectを参照。
- RootGraph
- グラフの階層化をしている場合に、ルートグラフを所有しているGameObjectを参照。
- 自グラフがルートの場合は、自グラフのGameObjectを参照する。
- ParentGraph
- グラフの階層化をしている場合に、親グラフのGameObjectを参照。
- 自グラフがルートの場合はnullを返す。
- Self
項目 | 内容 |
Noting | 更新しない。 |
Everything | 常に更新する。 |
Enter | ノードに入った時に更新する。 |
Execute | ノードが実行される時に更新する。 |
Manual | スクリプトから任意のタイミングに更新する。 |
参考:【Unity】Arbor3のparameter containerを使うときに知ってると便利なことメモ
スクリプト例(「parameter container」をGameObjectから検索し要素を取得、または格納する)
スクリプト例(「parameter container」をGameObjectから検索し要素を取得、または格納する)
using System.Collections; using System.Collections.Generic; using UnityEngine; using Arbor; //Arborの名前空間を定義しておく public class get_parameter_container : MonoBehaviour { // Start is called before the first frame update ParameterContainer pracon_01; //Arborのパラメーターコンテナ参照用 void Start() { int para_test01; //「parameter container」をGameObjectから検索し要素を取得、または格納する //変数para_test01から現在の数値を取得した後,1加算した数を格納し直す pracon_01.GetComponent<ParameterContainer>().TryGetInt("test01", out para_test01); para_test01 +=1; pracon_01.GetComponent<ParameterContainer>().SetInt("test01", para_test01); } }
- parameter containerの値をスクリプトで引用する
para_test01 = intParameter.parameter.intValue;
- parameter containerに値をスクリプトで格納する
intParameter.parameter.intValue = 5;
- Arborとはシンプルかつ強力なステートマシンとビヘイビアツリーのグラフエディタ
- Arbor3はステートマシン(FSM)とブレンドツリー(BT)で若干作り方のルールが違うので注意
チュートリアル:基礎編
チュートリアル:コーディング編
チュートリアル:AIエージェントの作り方
チュートリアル:コーディング編
- ArborFSMで使用できるスクリプトにはいくつか種類がある?
チュートリアル:AIエージェントの作り方
- AgentControllerとBehaviourTreeを使用して、プレイヤーを追いかけるAIエージェントの作り方について解説している
公式ドキュメント:スクリプティングStateBehaviour
- StateBehaviourをカスタマイズするには、StateBehaviour用のスクリプトファイルを作成し、行いたい処理を記述する必要がある
- プロジェクトウィンドウで右クリックし「作成」→「Aebor」→「StateBehaviour C# Script」でスクリプトファイルを作成する
- StateBehaviourとは、TimeTransitionやActivateGameObjectのようにArborFSMのステートの挙動を記述できるスクリプト
- ステート用の制御のほか、MonoBehaviourと同様に編集可能なパラメータやOnCollisionEnterなどのコールバックも使用できる
- 1つのステートに複数挙動を追加している場合、これらのコールバックはArbor Editorウィンドウで見た時の上から順に呼ばれるようになっている
- 作成したStateBehaviourをArborEditorにてステートに割り当てると、以下の各関数が呼び出される
- OnStateAwake
- 初めてステートに遷移してきたときに呼ばれる。
- OnStateBegin
- ステートに遷移してきたときに呼ばれる。
- OnStateUpdate
- ArborFSMのUpdate()のタイミングで呼ばれる。
- 毎フレーム呼ばれるかどうかはArborFSMのUpdate Settingsに依存する。
- OnStateLateUpdate
- ArborFSMのLateUpdate()のタイミングで呼ばれる。
- 毎フレーム呼ばれるかどうかはArborFSMのUpdate Settingsに依存する。
- OnStateEnd
- ステートから離れるときに呼ばれれる
- 作成したスクリプトにpublicもしくはSerializeField属性をつけた変数を宣言することでArbor Editorで編集可能になる
using UnityEngine; using System.Collections; using Arbor; public class TestBehaviour : StateBehaviour { public string myName; // 略 }
作成したスクリプトにpublicもしくはSerializeField属性をつけたStateLinkを宣言することでArbor Editorで接続スロットが表示される
using UnityEngine; using System.Collections; using Arbor; public class TestBehaviour : StateBehaviour { public StateLink nextState; // 略 }
- OnStateBegin()を以下のように変更する。
public override void OnStateBegin() { Debug.Log("OnStateBegin : " + state.name); }
- メンバ変数を以下のように追加する
public StateLink nextState;
- OnStateUpdate()を以下のように変更する
public override void OnStateUpdate() { if (Input.GetKeyDown(KeyCode.Space)) { Transition(nextState); } }
- ビヘイビアツリーのアクションに当たるところで「SubStateMachine」を使えば、1階層下にFSMのレイヤーが出来る
- 「EndStateMachine」で元の階層に戻る
ステート:ダメージ
遷移条件:Damage(Trigger)
ステート:ジャンプ
遷移条件:Jumping(True)
ステート:歩く
遷移条件:Walking(True)
ステート:走る
遷移条件:Running(True)
ステート:死亡
遷移条件:Alive(false)
◎Arbor3で使用するパラメータを外部から操作する(ParameterContainer)
遷移条件:Damage(Trigger)
ステート:ジャンプ
遷移条件:Jumping(True)
ステート:歩く
遷移条件:Walking(True)
ステート:走る
遷移条件:Running(True)
ステート:死亡
遷移条件:Alive(false)
◎Arbor3で使用するパラメータを外部から操作する(ParameterContainer)
[SerializeField] private BehaviourTree _tree; _tree.parameterContainer.SetFloat("パラメータ名", value);◎Animatorコンポーネントに各パラメータを取得する(GetInteger)
var animator = GetComponent<Animator>(); int i = animator.GetInteger("IntergerParameterName"); float f = animator.GetFloat("FloatParameterName"); bool b = animator.GetBool("BooleanParameterName");
プレイ中に接続ラインをマウスオーバーすると、現在値が表示されます。
接続ラインの右クリックメニューから「データ値を常に表示」を選択すると、マウスオーバーしなくても表示されるようになります。
全ての接続ラインの値を表示したい場合は、ツールバーの「デバッグ」メニューから「すべてのデータ値を表示」を選択すると切り替わります。
接続ラインの右クリックメニューから「データ値を常に表示」を選択すると、マウスオーバーしなくても表示されるようになります。
全ての接続ラインの値を表示したい場合は、ツールバーの「デバッグ」メニューから「すべてのデータ値を表示」を選択すると切り替わります。
コメントをかく