アマゾンバナーリンク

ディスプレイ広告

スポンサーリンク

【Unity】AI Behavior用マニュアル【実践編】

2021年3月19日

こんにちは!ジェイです。前回AI Behavirorのマニュアルを書きました。今回はそれを実際に使いながら解説していきます。

記事内広告

AIを作る

それでは1からAIを作ってみましょう。

  1. File>NewSceneで新しいシーンを作成する
  2. 3DObject>Planeを追加して、xyzを10,1,10に値を設定する。
  3. Asset>AIBehavior>Prefabs>avatar_empty.prefab(AI)を設置する
  4. Asset>AIBehavior>Prefabs>first_person_controller(Player)を設置する
  5. Playerに既にカメラが設定されているので、MainCameraを削除する

AIにNav Mesh Agentをアタッチされてるか確認してなければ、AddComponentで追加して、以下の手順でNavMeshを使えるようにしておきましょう。

  1. 地形と障害物のStaticにチェックする
  2. Window>AI>Navigationを選択
  3. Bakeタブを開きBakeする

次にAIとして動かしたいオブジェクトを選択して、ToolsからAI Behavior >Legacy Setupを選択すると、色々と勝手にアタッチされます。Animatorが設定されている場合は、Mecanim Setupでも構いません。

最初に色々なステートが付いているので、IdleとAttackと以外を「-」をクリックして消しておきます。(MecanimAnimationを使う場合は、MecanimAttackStateを、Legacy Animationを使う場合は、AttackStateの状態を設定すること)

最初はIdleからAttackにするので、IdleのEidtを押してIdleの編集をします。Global Triggersに下記のようなトリガーを追加して、条件をWithinDistanceTriggerにして、Distanceを10に設定します。

Beyond distance triggerは距離を超えたら発動するトリガーで、Within distance triggerは距離内に入ったら発動するトリガーです。

その前にアニメーションの設定を行います。AI Animation Stateスクリプトをみてください。これはアニメーションを管理するスクリプトで、ここに登録されているアニメーションの名前を以下のように指定します。

次にAttackのEditを押し、攻撃のステートの編集をします。
攻撃のAnimationsは攻撃用のステートにして、さらに攻撃用のメソッドを追加しておきます。この際にはAIBehavior.AttackDataを引数にとったメソッドが必要です。

using UnityEngine;
using AIBehavior;

public class EnemeyAI : MonoBehaviour
{
    public void EnemyAttack(AttackData attackData)
    {
        // 相手の方向を向く
        transform.LookAt(attackData.target);
        Debug.Log("EnemyAttack");
    }
}

このスクリプトをAIのrootオブジェクトに貼ります。すると下のように選択できるようになるので、呼び出したい攻撃メソッドを設定しましょう。

最後に攻撃時に行うアニメーションと移動プロパティを設定しておきましょう。Animationは再生するアニメーションの種類で、AIAnimatinonStatasで設定して名前から選ぶことができます。

MovementSpeedは移動速度で0にすると動きません。RotationSpeedは回る速度で0にすると回転しません。

実行結果

最初はアイドル状態でプレイヤーが近くに行くと攻撃状態に移り常にこちらを向いて攻撃アニメーションをしてきます。

Image from Gyazo

当たり判定をつける

次に当たり判定を付けるので、エラーがでないように、Stract.csを以下のように変えます。

namespace AIBehavior
{
	public struct AttackData
	{
		public AIBehaviors fsm;
		public AttackState attackState;
		public Transform target;
		public float damage { get { return attackState ? attackState.attackDamage : 0.0f; } }
		public float plusOrMinusDamage { get { return attackState ? attackState.plusOrMinusDamage : 0.0f; } }

		public AttackData(AIBehaviors aiBehaviors, AttackState attackState, Transform target)
		{
			this.fsm = aiBehaviors;
			this.attackState = attackState;
			this.target = target;
		}
	}
}

次にプレイヤーが攻撃できるように、Asset>AIBehavior>Prefabs>first_person_controller(Player)のShooter.csのprojectileにassets>AIBehaviorにprojectileをドラッグ&ドロップしましょう。

これでプレイヤーが弾を発射することができるようになります。

最後にAIにCapsule ColliderとRigidBodyを追加しましょう。これでAIに当たり判定が追加され弾を当てられるようになります。

指定したポイントを巡回させる

次にパトロールしている最中にプレイヤーが近づいたらAttackモードに入るという行動をさせてみます。

まずはじめに移動させたいポイントを空のオブジェクトの子オプジェクトとして、以下の様に作成します。

子オブジェクトのnode1~node4

PatrolをEditを押して編集モードにして、以下のように編集します。Patrol Points Groupに先ほど作っておいたpatrol_pointsをドラッグ&ドロップします。詳しくはこちら→Patrol State

初期状態と変更後の設定をします。ここでは初期状態はPatrolでプレイヤーが10以内に近づいたら、Attackに変化するという設定にしてます。

実行結果

パトロールをして、プレイヤー見つかったら、攻撃モードに移行します。

Image from Gyazo

ターゲットに近づき到達したら次の状態へ移行する

まず初めに近づいたら、次の状態にうつる条件をグローバルトリガーで指定しているので、それを削除してください。

次にIdleのEditを押して編集できる状態にして、以下の様に設定してください。BeyondDistanceTriggerはAIとゲットが一定以上距離が離れたら、発動するトリガーです。

この通りに設定するとアイドル状態でターゲットの距離が5以上になったらSeek Stateに移行するということになります。

次にSeek StateでEditを押して、以下のように設定してください。

実行結果

一定距離内に近づくとIdle状態になり停止し、一定距離以上になるとSeek状態になって追跡してくきます。

Image from Gyazo

ターゲットが近づいたら逃げる

プレイヤーがターゲットに一定の距離内に入ったら逃げるFlee状態を使用してみます。以下の様にEditを押して、IdleとFleeを設定しましょう。

IdleのEditを押して編集しましょう。

TriggersからwithinDistanceTriggerを選びDistanceを5に設定しましょう。これでターゲットが5より近くになったらFlee状態へ移行するという条件を指定できました。

Flee

上記の様に設定すると意図した動作をします。詳しくはFlee Stateを参照してください。

実行結果

Image from Gyazo

物を探す

AIがオブジェクトを探し、すべてなくなったらIdleに戻ります。最初にIdleとSeek状態を設定してから、追いかけるターゲットのタグをBlueとRedを指定します。

上記の設定でRedとBlueというタグをついたオブジェクトを探したらIdleに戻ります。詳しくはSeek Stateを参照してください。

実行結果

Image from Gyazo

近づいたら近接攻撃をしてくる

IdleとAttack状態をEditを押して設定します。

TriggersからTimerTriggerを追加して、UseCustomTagsの+を押してから、WithinDistanceTriggerを追加して以下の様に設定します。

AttackStateのAttack Methodを設定するにはまずAIオブジェクトにそのスクリプトをアタッチする必要があります。この場合は、ExamplesAttackComponent.csが必要になるので、先にアタッチしておきましょう。

実行結果

Image from Gyazo

近づいたら遠距離攻撃をしてくる

IdleとAttack状態を設定して、Attackの名前をクリックして、RangeAttackに変更します。

RangeAttack

RangeAttackの続き
以下の設定をする前に、AIにExampleAttackComponent.csをアタッチするのを忘れないようにしましょう。

実行結果

Image from Gyazo

一定距離を保って遠距離攻撃をしてくる

ターゲットが近づいてくると逃げて距離を置き攻撃してきて、ターゲットが離れると近づいて攻撃してくるAIを作ります。

IdleのEditを押して以下の様に編集します。

次にSeek StateでEditを押して、以下のように設定してください。

次にFleeでEditを押して、以下のように設定してください。

RangeAttackを以下の様に編集します。

実行結果

近づいてきて攻撃して、一定の距離を詰めると逃げます。

Image from Gyazo

近づくとガードする

近づくとガードして、距離が離れるとIdle状態にもどるパターンです。AIAnimationStatesで、設定してないアニメーションが各状態ごとのアニメーションが設定できないので、以下のように設定しましょう。

Idle

Defendの設定をする前にExampleDefendScriptをAIにアタッチしておきましょう。

Image from Gyazo

ダメージを受けるとアニメーションする

ダメージを受けると防御状態に入りHPがなくなると死亡状態になる

Idle状態をEditをクリックして編集します。

Got HitのEditを押して編集しましょう。

DefendのEditをクリックして、ExsampleGotHit.csをAIにアタッチします。

DeadのEditを押して編集しましょう。

実行結果

Image from Gyazo

1人が助けに入り一緒に行動する

2人のうち1人がやられているともう1人が助けに入ってくるパターンです。

助けられる方

助けられる方のIdle

助けられる方のGet Help

助けられる方のSeek

助けに入る方

助けに入る1人目のIdle

助けに入る方のHelp

助けに入る方のSeek

実行結果

Image from Gyazo

時間が経つと姿を消す

Idle
WithinDistanceTrigger(10以内に近づいたら)&&BeyondDistanceTrigger(5以上離れたら)&&TimerTrigger(0.5秒たったら)RangeAttack状態に移行する。

RangeAttackのEditをクリックして編集します。ExmpleAttackComponentをアタッチしておきましょう。

GetInvisible
状態になった時にカウントダウンを開始して、10秒間非表示にして、15秒間経ったら前の状態に戻る。

Image from Gyazo

適当に歩き回る

Idle

WanderのEditを押して以下の様に編集しましょう。

Loor LayersはAIが移動するのを許可するレイヤーで、設定してないと動けなくなります。床のオブジェクトにFloorと名前を付けて、Floorを設定してあげましょう。

AnchorPointは目標となる地点で、空のオブジェクトを作り歩かせたい好きな座標に作ってアタッチしましょう。

実行結果

Image from Gyazo

目標に近づいて攻撃しながら距離をとる

初めにAIの前にSeek Targetを後ろにFlee Targetを空のオブジェクトとして作っておきます。

Specify Seek TargetにSeek Targetを設定しているのが注意しましょう。Seek Targetは探索状態の時の目標です。Seek Targetが見つかったら、Flee状態に移行します。

Flee

Fixed ModeにFixed Target(固定モード)をしてます。

AttackのEditを押して編集します。

Inherit Previous State Movementにチェックすると少しずつ後ろに後退します。Attacks Before Reloadは残りの攻撃回数で、この回数だけ攻撃をするとReload Stateに移行します。

実行結果

Image from Gyazo

複数の的に向かって適切な攻撃をする

以下の様にオブジェクトを配置します。

avatar_empty position x 0 y 0 z -10
Cube x 0 y 1 z -3.32

Camera

Player

Feet

Torso

Head

Idle

Attack

Aim Meters Above Targetの値を0にしておきましょう。この値の分だけターゲットの座標より上にいくようになるので、正確に当てるために0にします。

実行結果

Find Visible Targets Onlyをチェックして、見えてるオブジェクトのみ、攻撃するように設定しているのが肝です。

Image from Gyazo
+1