Unity + Arborで敵AIデータを使い回す方法　〜ビヘイビアツリー編〜

[一つ前の記事](https://qiita.com/asiram/items/7fcf50d10f26f5ae2e87)ではArborのビヘイビアツリーを使うときに大事なポイントを紹介しました。
この記事では、ビヘイビアツリーにて敵AIロジックを使い回すための方法を解説します！

環境
Unity 2020.2.1f1
Arbor 3.7.8

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">Arborのビヘイビアツリーでは「Sub Behaviour Tree Reference」とパラメーターを使うと、行動の使い回しができて便利です <a href="https://t.co/VW3WGHz9xa">pic.twitter.com/VW3WGHz9xa</a></p>&mdash; asiram@unityゲーム開発 (@asiramasiram) <a href="https://twitter.com/asiramasiram/status/1359492462033604608?ref_src=twsrc%5Etfw">February 10, 2021</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

# どういうときに役立つの？
普通ゲームで作成する敵のロジックは複数になります。
Arborでは作成したビヘイビアツリーは、コンポーネントをコピー・ペーストすることで、グラフのコピーができます。
が、こうやってコピーされた敵AI達は、全てに影響する変更をしたくなった際に、コピペしたグラフを一つ一つ開いて修整せねばなりません。
これはツライ…
![old_graph.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62924/478c14e7-8cb5-b9b4-7bb5-dbb6f99ad3db.png)

そこで、今回紹介する方法を使えば、敵AIの行動単位で部品化して使い回せるようになります。
こうすると、一つの行動部品を修整すれば参照している敵全ての行動を修正することができます。
工数削減です！
![new_graph.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62924/5d2ef216-e0f0-8585-877c-66e65239fee5.png)

# 使い回すために使用するArborの機能
使い回す方法を説明する前に、必要なArborの機能を紹介します。
ざっとこんなところでしょうか。
（アクションとはみたいな基本的なことは説明しません。[前回の記事](https://qiita.com/asiram/items/7fcf50d10f26f5ae2e87)を参照してください

- 外部参照のビヘイビアツリーを再生するためのアクション：`Sub Behaviour Tree Reference`
- 参照先のビヘイビアツリーに情報を渡すためのパラメーター

## Sub Behaviour Tree Reference アクション
このアクションが使い回しのポイントです。
Sub Behaviour Tree Reference アクションは、外部のビヘイビアツリーを再生するためのアクションです。
「外部のビヘイビアツリー」とは言っていますが、ほとんどプレハブ化したビヘイビアツリーを使用するのが一般的かなと思います。
![スクリーンショット 2021-02-10 19.37.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62924/fc8f5706-b5b7-4177-a4a0-89e037bcfdb8.png)
これは、「SoloTargetCastAttack」というビヘイビアツリーがアタッチされたプレハブを読み込ませているSub Behaviour Tree Reference アクションです。
こちらの例ではプレハブを読み込ませていますが、他の方法(階層から取得など)を選択することもできるようです。
ちなみに、下にずらずら並んでいるのはパラメーターです。
こちらは後で触れるので覚えておくとよいです！

## パラメーター
Arborにはパラメーターをとる手段がいくつか用意されていますが、今回扱うのはグラフに紐づくパラメーターです。
今回のパラメーターの用途は、使い回しする行動にパラメーターを与えて、**挙動をある程度変える目的で使用します**（例えば、攻撃力を変えるなど）。
![スクリーンショット 2021-02-10 19.46.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62924/d0d1a5ba-f34e-e780-9620-82b9e07396be.png)
グラフのパラメーターは、Arbor Editorの左側で設定することができます。
`+`マークを押して型を選択、型名の横にパラメーター名を定義して、その下に値を設定できます。
上の例だと、`String`が型名、`attack_name`がパラメーター名、`突撃`が設定された値ですね。

# 敵AIデータを使い回す方法
では実際に敵AIデータを使い回す方法を見ていきましょう。
手順はこんな感じです。

```
1. 部品化させたいAI行動を作成、プレハブ化する（必要であればパラメータを定義）
2. 敵A本体のビヘイビアツリーを作成する
3. 2.のビヘイビアツリー内にSub Behaviour Tree Reference アクションを組み込む
4. 3.に1.で作成したプレハブを設定する
5. 必要であれば3.にパラメータの設定を追加する
```
順番に見ていきましょう。

## 1. 部品化させたいAI行動を作成、プレハブ化する
まずはこんな感じで、`BehaviourTree`コンポーネントがアタッチされただけのGameObjectを作成、プレハブ化しましょう。
![スクリーンショット 2021-02-10 19.59.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62924/e003167d-c69a-ad80-1a14-e10bd9271671.png)
（画像だと`Play On Start`とか`Update Settings`とかいじってありますが、普通に使う分にはそのままの設定で良いと思います）

次に、このプレハブに設定されているビヘイビアツリーの中身を作成しましょう。
これが使いまわせる部品になります。
つまり、「SoloTargetCastAttack」という行動が敵A、敵B、敵Cにも参照させて使いまわせるようになります。
![スクリーンショット 2021-02-10 20.04.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62924/02e6345a-c421-18ba-2169-360a9892b949.png)
今回はこんな感じにして、Sequencerに複数のアクションが紐づく構成にしています。
再利用しやすいように、分岐処理などは避けてシンプルに組みました。
メンテナンスのしやすさも考えて、あんまり複雑にしないほうがいいかなと思います。

### ワンポイント：パラメータを追加する
パラメータは必要なければ特に追加しなくてもOKですが、再利用性を高めるためにもパラメータを使用して各値を外部から変更できるようにすると使いやすくなります。
![スクリーンショット 2021-02-10 21.29.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62924/4121e031-a7e9-bae9-937c-1d4611b26a69.png)
先ほどのグラフの一部です。
パラメータを定義して、アクションの各設定値に割り当てることができます。
今回は、「Enemy Action Cast Start」の`SkillName`にパラメーターの`attack_name`(名前がよくないかも)、`CastTime`にパラメーターの`cast_time`が割り当たっています。

パラメーター名の右隣にある色のついた場所からドラッグ&ドロップで、アクションの設定値に割り当てることができます。
こうすることで、外部からこれらのパラメーターが設定された時に値が各アクションに反映されるようになり、例えば敵キャラによって攻撃力を変えるなどができるようになります。

ちなみに、このような使い方をしたときパラメーターに設定されている具体的な値は、デフォルト値扱いになり、外部からパラメーターとして渡されない場合に使用される値になります。

## 2. 敵A本体のビヘイビアツリーを作成する
この手順は単純にいつも通りビヘイビアツリーを対象のオブジェクト(敵)に対して作成すればOKです。

## 3. 手順2.のビヘイビアツリー内にSub Behaviour Tree Reference アクションを組み込む
とりあえずこんな感じにしました。
![スクリーンショット 2021-02-10 21.44.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62924/4a401009-1ac6-eb15-d9af-6b04ce38a68b.png)
（自作デコレーターをつけて、HP条件を満たしていないときは通常攻撃。みたいなニュアンスの設定にしてみましたよ

## 4. 手順3.に手順1.で作成したプレハブを設定する
最初の手順で作成したプレハブをSub Behaviour Tree Reference アクションに設定します。
`ExternalBT`にプレハブをドラッグ&ドロップで設定できます！
![スクリーンショット 2021-02-10 21.49.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62924/15d6910f-64e4-0b66-acd3-17076e54475e.png)
こんな感じ。
パラメーターが必要なければこれで終わりです。
ゲームを実行して挙動を確かめてみましょう。
条件を満たしていれば、Sub Behaviour Tree Reference アクションに処理が流れて、設定したビヘイビアツリーに処理が移っていくことがわかると思います！

## 5. パラメータの設定を追加する
Sub Behaviour Tree Reference アクションの下の方の`+`マークから、パラメーターを設定することができます。
![スクリーンショット 2021-02-10 21.53.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62924/8e97d422-340f-059f-985e-b372a765543b.png)
最終的にこんな感じになりました。

これでAI行動を部品化して、さらにパラメータによって挙動を変えることができるようになりました！
異なる敵に同じ行動をさせたい場合は、2~5の手順を繰り返してSub Behaviour Tree Reference アクションにプレハブ化したビヘイビアツリーを設定しましょう。

今回部品化した行動に修正を加えたいときは、手順1.で作成したビヘイビアツリー一つを修正すれば全ての参照している敵に反映されます。

# まとめ
敵AIデータを使い回すために必要なArborの機能、手順を解説しました。
これで悲しいコピペ地獄は避けられそうです。
自分はまだ試していませんが、ステートマシンの方でもおそらく同じような使い方ができると思うので、興味がある方は試してみると良さそうです。