■Unity開発メモ用のWiki◎現在扱っていること・Unity全般・MMDからUnityへの変換してインポート・MMDの仕様把握・BlenderでMMDモデルのカスタム

目次



UnityのAnimatorをビヘイビアツリーで制御する

参考:UnityのAnimation遷移はビヘイビアツリーで管理するのが便利かもしれない
  • Animatorは「コーギーエンジン・ Corgi Engine」又は「トップダウンエンジン・TopDown Engine」を使う
  • ビヘイビアツリーは「Arbor3」を使う

ParameterContainerを設定する

  • ParameterContainerにAnimatorのパラメーターを設定していく

セレクターノードにつけるDecoratorノードの作成

  • 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);      
    }
}

ビヘイビアツリーの構築

  • 「root」→1段目の「セレクター」→2段目の「セレクター」
    • ジャンプ中で無いなら左側のノード群へ進み、ジャンプ中なら右側のノード群へ進む
  • 1段目の「セレクター」→2段目の「セレクター」→アクションノード
    • アクションノードは「ParameterContainer」でそのアクションノードを実行するか判定し、「AnimatorCrossFade」を使いアニメーションを遷移する
  • アクションノードは左から「Run」「Walk」「Idle」のアニメーションステートになっている

アクションノードの作り方

参考:ActionBehaviourスクリプトファイルの作成
基本的な流れ
  • ActionBehaviourを継承したクラスを作成する
  • OnExecute()メソッドをオーバーライドし、挙動を自分で定義する
  • OnExecute()メソッドの最後にFinishExecute()を呼んでノードを終了する
    • これやらないと永遠にそのアクションを実行し続けるので注意!毎フレーム攻撃とかになる

Decoratorノードの作り方

参考:Decoratorスクリプトファイルの作成
基本的な流れ
  • Decoratorを継承したクラスを作る
  • OnConditionCheck()メソッドをオーバーライドし、成功/失敗を表すtrue/falseを戻り値として返す

ビヘイビアツリーの基礎知識

参考:Behavior Tree ワタシハ ビヘイビアツリー チョットデキル
参考:Unity + Arborで敵AIを作るならこれだけは覚えておけ!集〜ビヘイビアツリー編〜

基本的な考え方
  • ツリー状の構造によって、次に行う行動を決定する
  • ビヘイビアツリー幹と葉っぱの2つから成り立つ
    • 幹に当たるのが「コンポジットノード」
    • 葉っぱに当たるのが「アクションノード」
  • それぞれのノードは、実行結果の状態(Success / Failure / …)を判定し、その戻り値を親ノードに返す

  • コンポジットノードの役割
    • コンポジットノードの役割はそのノード以下の部分木(ブランチと呼ばれる)によって表現される挙動(サブタスク)を制御すること
    • Arbor3だと「Selector」と「Sequencer」にあたる

  • アクションノードの役割
    • アクションは葉ノードとして書き、Behavior Tree 外に実装された具体的な関数を呼び


制御文を実現するためのノード(Decoratorノード)
  • if文、while文、for文 を実現するためのノード
  • アクションノードやコンポジットノードに取り付けて、条件判定を行う

Arbor3での変数の使い方(データーフロー)

  • データフローとは?
    • データフローとは、ノードの処理結果を他のノードに受け渡すためのデータの流れを言います。
    • データの入出力スロットを接続するとデータフローを活用できます。
  • 「ヒエラルキー」やインスペクターの「パラメーターコンテナ」から直接ノードにドラッグ&ドロップして値を設定出来る
参考:データフローの入出力をスクリプトから行う方法

出力スロット(OutpotSlotIntなど)の作り方

公式ドキュメント
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の作り方

FlexibleField関連クラスを使用すると、固定値の指定やパラメータ参照もしくはデータフローからの入力を切り替えて参照できます。
複数の参照方法を選択できますので柔軟に値が設定できます。
  • メリット
    • 他の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を返す。

ノードの更新タイミング

項目内容
Noting更新しない。
Everything常に更新する。
Enterノードに入った時に更新する。
Executeノードが実行される時に更新する。
Manualスクリプトから任意のタイミングに更新する。

parameter container

参考:【Unity】Arbor3のparameter containerを使うときに知ってると便利なことメモ

スクリプト例(「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;

Arbor3メモ・TIPS

  • Arborとはシンプルかつ強力なステートマシンとビヘイビアツリーのグラフエディタ
  • Arbor3はステートマシン(FSM)とブレンドツリー(BT)で若干作り方のルールが違うので注意

チュートリアル・デモ

チュートリアル:基礎編
チュートリアル:コーディング編
  • ArborFSMで使用できるスクリプトにはいくつか種類がある?
チュートリアル:コインプッシャーを作ろう
チュートリアル:AIエージェントの作り方
  • AgentControllerとBehaviourTreeを使用して、プレイヤーを追いかけるAIエージェントの作り方について解説している

StateBehaviourをスクリプトでカスタマイズする

公式ドキュメント:スクリプティング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;
	// 略
}

接続先へ遷移する

遷移したいタイミングでTransitionを呼ぶと遷移できる
Transition( 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);
    }
}

ビヘイビアツリーとFSM(ステートマシン)を組み合わせたい

  • ビヘイビアツリーのアクションに当たるところで「SubStateMachine」を使えば、1階層下にFSMのレイヤーが出来る
    • 「EndStateMachine」で元の階層に戻る

Arbor3を使ったアニメーションの遷移管理

ステート:ダメージ
遷移条件: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");

接続ラインに常に値を表示させる

プレイ中に接続ラインをマウスオーバーすると、現在値が表示されます。
接続ラインの右クリックメニューから「データ値を常に表示」を選択すると、マウスオーバーしなくても表示されるようになります。
全ての接続ラインの値を表示したい場合は、ツールバーの「デバッグ」メニューから「すべてのデータ値を表示」を選択すると切り替わります。

BehaviourTree(ビヘイビアツリー)のレファレンス

Action・Agent関連

Action
Agent

Composite(複合) リファレンス

Composite

Decorator(制御) リファレンス

Decorator

Arborの組み込みComponentのリファレンス

Arborの組み込みComponent

Behaviour(FSM?)関連

コメントをかく


「http://」を含む投稿は禁止されています。

利用規約をご確認のうえご記入下さい

Menu

【メニュー編集】

スカイリム関連

スカイリム関連


Menu

【メニュー編集】

スクリプト関連

フリーエリア

管理人/副管理人のみ編集できます