概要:

今回も敵の動作をBehaviorGraphで作成していきます!
動作としては以下フローになります。
1)プレイヤーを見つけるまでは指定の場所を巡回する。
2)プレイヤーをみつけたら追いかける
3)プレイヤーに接近したら攻撃を行う

準備:

アセットをダウンロードしてUnityを開きます。

アセット:https://www.patreon.com/posts/117604296

Unity中で開くシーン:

Assets/Scenes/AIScene
を開いておきます。

基本的な使い方やパッケージ導入などは前回の記事を参照
https://qitz-plus.x0.com/unitybehaviorgraph%e5%85%a5%e9%96%80%ef%bc%9a%e3%81%9d%e3%81%ae%ef%bc%91%ef%bc%88%e5%b0%8e%e5%85%a5%e7%b7%a8%ef%bc%89/

今回作成したBehaviorGraph:

今回作成した敵の行動のBehaviorGraphはこちらになります!

作成したEnemyStatus解説:

BlackBordから「Create new enum type」を選択し新しくenumを作成します。

以下のように作成

作成したGraph解説:

Graphの動作とフローはざっくり以下のような動きとなっています!

まずは、OnStart後にSwitchで「EnemyStatus」をみて
・「Usually」の場合はパトロールを実行
・「FindTarget」の場合は追撃を実行
するように分岐させています。

・「Usually」の場合は次の「CancellablePatrol」という新しく作成したActionに進みWayPointsを巡回します。
・Targetとの距離が「ThresholdDistance」以下になったら巡回をキャンセルして次のNodeに遷移します。
・SetEnemyStatusを「FindTarget」に切り替えます。

FindTarget以下のフローでは「navigate to」を使いTargetまで移動させています。
Inspectorで以下のように設定しています。
・Agent:Self
・Target:Target
・Speed:6:(敵が追いかけてくるときのスピード)
・DistanceThreshold:2:この距離を下回ると次のフローに進む
・AnimatorSpeedParam:SpeedMagnitude:Animatorで設定されているキャラクターSpeedのパラメーター名

set animation triggerでは以下のようにInspectorで設定しています。
・Trigger:Attack
・Animator:Self
・TruggerState:ON

その後「Wait」で2秒待機します。(連続で実行するとTriggerが連続で実行されてアニメーションが再生されないので)

その後「Branch」を使いTargetとの距離が6以上はなれているか否かで判定分岐させます。
Trueの場合はSetEnemyStatusを「Usually」に切り替えます。

BrackBord解説:

以下のようにBlackboardを設定します。

・Self:GameObject:自分自身を示すゲームオブジェクト
・EnemyStatus:Status:作成したEnumで敵の状態を示す
・WayPounts:GameObjectList:GameObjectのリストで敵が巡回する場所を指定します。
・Target:GameObject:Playerなど敵が追撃するTargetの参照

Hierarchyの中EnemyのInspectorでは以下のように設定しています。
・BehaviorAgentをアタッチする
・BehaviorGraphに先ほど作成したBehaviorGraphを指定する
・BlackboardVariablesに以下のように設定

作成したCancellablePatrol解説:

今回作成したActionのCamcellablePatrolは以下のように作成しました。

右クリック=>Add=>Action=>Create new Actionを選択

「CamcellablePatrol」という名前で作成しEditorで以下のようにスクリプトを組んでみました!

using System;
using Unity.Behavior;
using UnityEngine;
using Action = Unity.Behavior.Action;
using Unity.Properties;
using UnityEngine.AI;
using System.Collections.Generic;

[Serializable, GeneratePropertyBag]
[NodeDescription(name: "CancellablePatrol", story: "Cancellable Patrol", category: "Action", id: "533f21ff85abc15096db357c2039e9d2")]
public partial class CancellablePatrolAction : Action
{
    [SerializeReference] public BlackboardVariable<List<GameObject>> WayPoints;
    [SerializeReference] public BlackboardVariable<NavMeshAgent> Self;
    [SerializeReference] public BlackboardVariable<GameObject> Target;
    [SerializeReference] public BlackboardVariable<float> ThresholdDistance;
    [SerializeReference] public BlackboardVariable<float> PatrolSpeed;
    [SerializeReference] public BlackboardVariable<string> AnimatorSpeedParam;
    Animator animator;
    int destPoint = 0;

    protected override Status OnStart()
    {
        Self.Value.speed = PatrolSpeed;
        animator = Self.Value.GetComponent<Animator>();
        GotoNextPoint();
        return Status.Running;
    }

    void GotoNextPoint()
    {
        if (WayPoints.Value.Count == 0)
            return;

        Self.Value.destination = WayPoints.Value[destPoint].transform.position;

        destPoint = (destPoint + 1) % WayPoints.Value.Count;
    }

    protected override Status OnUpdate()
    {
        float currentDistance = Vector3.Distance(Target.Value.transform.position, Self.Value.transform.position);
        if(currentDistance < ThresholdDistance.Value)
        {
            return Status.Success;
        }
        animator.SetFloat(AnimatorSpeedParam.Value, Self.Value.speed);
        if (!Self.Value.pathPending && Self.Value.remainingDistance < 0.5f)
        {
            GotoNextPoint();
        }
        return Status.Running;
    }

    protected override void OnEnd()
    {
    }
}

#

No responses yet

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA