ながつきぶろぐ

Unityのこととかゲームのこととか書けたらよいなブログ。

Arbor3のビヘイビアツリーでAIをつくる【後編】

この記事は、「Unity アセット真夏のアドベントカレンダー 2018 Summer!」8/27分の記事の後編になります。
Unity アセット真夏のアドベントカレンダー 2018 Summer! – Unity公式 Asset Portal

前編はこちらからどうぞ。 nagatuki.hateblo.jp


解説 続き

プレイヤーが近くにいると立ち止まるようにする

立ち止まる(=待機する)処理を追加していきます。

処理の追加

「Arbor Editor」ウィンドウで右クリックし、「アクション作成」を選択。
その後出てくるリストの一番下にある「Waitコンポーネントを選択します。
そして、その「Wait」の「Seconds」を1にします。これで1秒待機するという動きになります。

f:id:nagatuki_elv:20180825193955p:plain

ビヘイビアツリー上に、「Wait」の処理が追加されました。
しかし、矢印が繋がっていません。そのため、このままでは処理が実行されません。

分岐を作成する

ここからちょっとややこしくなるかもです。

先ほどと同じく「Arbor Editor」ウィンドウで右クリックし、今度は「コンポジット作成」を選択。
その後出てくるリストの一番下にある「Selectorコンポーネントを選択します。

f:id:nagatuki_elv:20180825194350p:plain

ビヘイビアツリー上に、「Selector」が追加されました。
こちらは主に処理の分岐に用いられます。詳しくは後述します。

アクションと異なり、矢印を繋ぐコネクタが上下にありますね。
下のように、ノードの位置を変えたり矢印を繋ぎましょう。

  • Wait」を「Agent Move On Waypoint」より左に配置する
  • Root」の矢印から、「Selector」の上部に矢印を繋ぐ
  • Selector」の下部から、「Wait」と「Agent Move On Waypoint」に矢印を繋ぐ

f:id:nagatuki_elv:20180825194906p:plain

上のようになっていればよいです。
ただ、これで実行したとしても敵が動かなくなります。
Wait」がひたすら実行されてしまっていますので、「Wait」を実行する条件を設定してやらないといけません。

Wait」を実行する条件を作成する

ここで、条件を決めるための処理を作成する必要があります。
すみません、ソース書きます!
DistanceCheck.csという名前でソースを作成します。

公式のチュートリアルからソースを拝借します。引用が問題ありそうなら修正します…。

using UnityEngine;
using Arbor;
using Arbor.BehaviourTree;

/// <summary>
/// Condition OK if the distance between self object and Target is not more than Distance!
/// </summary>
[AddComponentMenu("")]
public class DistanceCheck : Decorator
{
    [SerializeField]
    private FlexibleTransform _Target;

    [SerializeField]
    private FlexibleFloat _Distance;

    protected override bool OnConditionCheck()
    {
        // True if the Target exists and the distance is less than or equal to the Distance field.
        Transform targetTransform = _Target.value;
        return targetTransform != null && Vector3.Distance(transform.position, targetTransform.position) <= _Distance.value;
    }
}

上記の処理を、「Wait」に付与します。
Wait」の右上にある歯車をクリックし、「デコレータ追加」を選択します。

f:id:nagatuki_elv:20180825200437p:plain

「Script」の中に先ほど作成したソース「DistanceCheck」がありますので、追加します。 「Wait」ノードに処理が追加されたので、以下の設定を行います。

  • AbortFlags:Everythings
  • Target:Player
  • Distance:15

f:id:nagatuki_elv:20180825201009p:plain

ここまでの流れで、普段は決まったルートを徘徊、
プレイヤーが近くにいると止まるようになりました。
プレイヤーとの距離が離れると、再びルートを徘徊します。

f:id:nagatuki_elv:20180825201240g:plain

プレイヤーが近くにいると接近するようにする

さらに追加で処理を追加しましょう。

「Arbor Editor」ウィンドウで右クリックし、「アクション作成」を選択。
続いて「Agent」→「AgentMoveToTransform」を選択します。
こちらは、指定のTransformにNavMeshAgentを移動させる処理です。

次に、『「Wait」を実行する条件を作成する』でやったように、
AgentMoveToTransform」に対して「DistanceCheck」を追加します。
設定するパラメータは以下の通りです。

  • AbortFlags:Everythings
  • Target:Player
  • Distance:10

最後に、「AgentMoveToTransform」のノードを「Wait」ノードよりも左へ移動し、
Selector」の下部と矢印を繋ぎます。

f:id:nagatuki_elv:20180825202301p:plain

こうなっていれば完成!

f:id:nagatuki_elv:20180825202417g:plain

距離によってルート徘徊、停止、接近を切り替えるようになりました!

デモ

以下に今回の実装をもとにしたデモを公開しました。
WebGLが見られる環境で確認できます。

アドカレ2018 Arbor3のAIデモ | 無料ゲーム投稿サイト unityroom - Unityのゲームをアップロードして公開しよう

ノードの種類について

ビヘイビアツリーは、「ノード」と呼ばれる処理や判定の部分を矢印で繋いで制御しています。
概要部分については詳しくはググっていただいた方がわかると思いますが、Arbor3独自の言い回しがあったりするので軽く説明いたします。

ルートノード

f:id:nagatuki_elv:20180818214307p:plain
ビヘイビアツリーの開始点となる場所です。1つしか存在できません。
ここから矢印を下に下にと伸ばしていきます。

コンパレータノード

これより下にぶら下がっている処理の流れを制御できます。
よく使うのは、左から順に見ていって条件を満たしたものを「1つだけ」実行できる「Selector」と、
左から順に処理を実行して条件を満たしていないものがあったら以降の処理を実行しない「Sequencer」の2つです。
f:id:nagatuki_elv:20180818214508p:plain

f:id:nagatuki_elv:20180818214557p:plain
「左から」ではなく「ぶら下がっているものをランダム」でチェックする「Random Executor」「Random Selector」「Random Sequencer」というものもありますが、
これらは使う場面が限定的なので割愛します。(そもそもよくわかっていない)

アクションノード

一番よく使うメインノード。実際の処理部分になります。
有効になった時点で、そのノードの処理が実行されます。

デコレータ

コンパレータノードまたはアクションノードに対して追加で設置ができる、条件分岐の処理です。
早い話がif分岐です。

これがノードについていると、その条件を満たしているか満たしていないかに対する切り分けができます。
「プレイヤーが近くにいれば」の部分になりますね。

サービス

あんまり使わないと思いますが、ノードがアクティブな時に追加で実行する処理を配置できます。
コンパレータノードまたはアクションノードに対して追加で設置ができます。
補助的な役割になるのではないかと思います。
サンプル処理はありません。なのであんまわからない

f:id:nagatuki_elv:20180821215440p:plain ちなみに、Projectタブ内で右クリック、またはメニューバーの「Create」から「Arbor」の項目を選ぶと、
Arborのテンプレートコードを作成することができます。
ビヘイビアツリー用のソースは「BehaviourTree」の中にあります。

使用作品

私がArbor3を使ってAIを作った作品たちです。よかったら遊んでみてね。

Escape Maze Room

f:id:nagatuki_elv:20180509224027p:plain
3D迷路。初めてAIを使った作品です。
本番ステージの徘徊者(触れるとゲームオーバー)のAIを作成しました。

f:id:nagatuki_elv:20180818204649p:plain

チュートリアルをちょっと弄った程度です。
Escape Maze Room | 無料ゲーム投稿サイト unityroom - Unityのゲームをアップロードして公開しよう

GrazeShooter

f:id:nagatuki_elv:20180611212629g:plain
対戦型シューティング。
1Pモード時の対戦相手のAIを作成しました。

f:id:nagatuki_elv:20180818204918p:plain

時間がなかったためランダム移動およびランダムで3種類のショットを打ち分けるというクソザコAIになっております…

Graze Shooter | 無料ゲーム投稿サイト unityroom - Unityのゲームをアップロードして公開しよう

天井のスキマ!ひよこバトル

天井のスキマ!ひよこバトル
現在開発中の生き残り型対戦アクションゲーム。
コンピュータのAIを作成しております。
天井のスキマを見つけて移動したり、アイテムを見つけたら取れる範囲で取りに行ったり、アイテムを使うべき状況になったら使ったり、押し合いになったらジャンプで避けたりします。
不調のため制作が止まっている件については非常に申し訳ない…

f:id:nagatuki_elv:20180818205705p:plain

一番作りこんでいるといってもよいですね。(ノードが多すぎるので説明は割愛)
※現在以下で公開中のプロト版はArbor2使用のためビヘイビアツリーによるAIは使っていません。
開発中のものはArbor3にバージョンアップしてビヘイビアツリーを使用しています。
天井のスキマ!ひよこバトル | 無料ゲーム投稿サイト unityroom - Unityのゲームをアップロードして公開しよう

おわりに

Arbor3によるビヘイビアツリーでAIを作る方法を紹介しました。
ビヘイビアツリーってなんぞやって人もご理解いただけたなら幸いでございます。

久々にボリューム大き目の記事を書いたので非常に疲れたぞい…