Behavior Designerを使ってAIを作ってみる
Behavior DesignerをImportし、さっそくAIを作り始める。
Seekを追加したところで"NavMesh"がないよ!と怒られる。
Seekを使うには、NavMeshが必須らしい。
NavMesh
Unity公式のリファレンスを確認
ナビゲーションと経路探索
簡単にまとめると、NavMeshが歩行可能な面のデータであり、NavMesh Agentはそのデータを元に経路探索を行う。
連続した面ではなく、溝やフェンスを飛び越えるなどを可能にするにはOff-Mesh Linkを使用する。
また、NavMesh Obstacleは障害物となるオブジェクトを指す。
NavMeshはジオメトリから自動的に生成される。
おもちゃラボさんのブログがとてもわかりやすいです。
【Unity】NavMeshで経路に沿って動かす
スクリプトはこんな感じ。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;
public class NavMeshTest : MonoBehaviour
{
[SerializeField]
private Transform _target;
private NavMeshAgent _agent;
private void Start()
{
_agent = GetComponent<NavMeshAgent>();
}
private void Update()
{
_agent.SetDestination(_target.position);
}
}
とっても簡単に障害物を避けつつ、目標に向かって進むAIが完成。
よく見るとAIの端が障害物にかすってるように見えます。
これはベイク時の初期設定でAgetn Radiusの値が0.5になっていたからで、Sceneビューで確認すると壁に沿ってパスが引かれてしまっています。
これを回避するために値を2にします。
こうすることで壁から余裕をもってパスを引くことができました。
無事、壁にぶつからず、すれすれで障害物を避けるようになりました。
Behavior Designer
また、先ほどエラーで怒られたBehavior DesignerのEditor上でSeekを追加することで同様の挙動をすることが確認できました。
最終的に以下のようにすることでNavMesh内でTargetの探索を行い、視界に捉え次第、捕獲に向かうAIができました。
おまけ
Abort Typeの違い
SequenceのInspectorを確認すると、Abort Typeというプルダウンがあり、None, Self, Lower Priority, Bothの4つから選択することができます。
これが少し紛らわしいのですが、先ほど作成したTreeをベースに説明すると、今回のケースでは実行直後にAIの視界内にTargetはいないのでCan See Object
はFailureを返します。
その後はSearch
がRunningとなり、探索を行ったきりになってしまい、Seek
に行くことはありません。
これはBehavior Designerでは最適化のために他のノードが実行中のとき、他のノードは実行されないからです。
今回のケースではSearch
中であっても、視界内にTargetを捉え次第Can See Object
からSeek
に遷移して欲しいのでSequence
のAbort TypeをLower Priorityに変更します。
このようにすることでSearch
を実行中でも、Can See Object
は常に評価され、Successを返し次第Seek
が実行されます。
Selfに変更すると、Seek
が実行中であっても、Can See Object
がFailureを返し次第Seek
に遷移させることができます。
BothはLower PriorityとSelf、両方を有効にしたい時に使用します。
Day2につづく
超簡単なAIを作る回 (Day2)