日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

怪物行为树案例_Behavior Designer行为树(简单实现巡逻)

發布時間:2024/9/3 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 怪物行为树案例_Behavior Designer行为树(简单实现巡逻) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

做一個簡單敵人巡邏

導入資源后,直接添加一個Tasks-> Actions->Patrol行為樹任務

Paste_Image.png

然后進入Inspector設置參數

Paste_Image.png然后我們把地形烘培,因為行為樹還是依靠Navigation的

Paste_Image.png

接下來我們再給我們的敵人添加導航的組件這樣我們怪物的巡禮就完成了

Paste_Image.png

35分10秒.gif

會追擊所看到的敵人

下面是設置行為樹的執行關系

Paste_Image.png

首先我們設置三個變量,一個是游戲對象的速度/旋轉速度和所要追擊敵人的Transform。

Paste_Image.png然后我們設置所需要看到的角度對象以及距離。

Paste_Image.png

下面我們設置看到目標敵人后就需要去追擊敵人。所以Target Transform就要設置敵人的Transform。

Paste_Image.png最后設置好當我們沒看到敵人所要到達的目標

Paste_Image.png

Paste_Image.png

Paste_Image.png

Paste_Image.png我們用最后一個也就是說當看到的時候就會去追擊敵人。

Paste_Image.png

當離開了視野范圍的時候就會朝著它原來的目標前進

Paste_Image.png

自寫Seek任務

直接讓它繼承自Action。

using BehaviorDesigner.Runtime;

using BehaviorDesigner.Runtime.Tasks;

using System.Collections;

using System.Collections.Generic;

using UnityEngine;

public class MySeek : Action {

public float speed;

public SharedTransform target;

public float arriveDistance = 0.1f;

private float sqrArriveDistance;

public override void OnStart()

{

sqrArriveDistance = arriveDistance * arriveDistance;

}

//當進入到這個任務的時候,會一直調用這個方法,一直到任務結束 一返回一個 成功或者失敗的狀態

//那么認為結束 如果返回一個running的狀態,那這個方法會繼續被調用

public override TaskStatus OnUpdate()

{

if (target == null||target.Value==null) {

return TaskStatus.Failure;

}

transform.LookAt(target.Value.position);

transform.position = Vector3.MoveTowards(transform.position, target.Value.position, speed * Time.deltaTime);

if ((target.Value.position-transform.position).sqrMagnitude

return TaskStatus.Success;//如果距離目標位置的距離比較小,認為達到目標文字,直接Return成功

}

return TaskStatus.Running;

}

}

我們可以看到我們自己寫的任務被Action 自動添加了進去

Paste_Image.png

自寫CanSeekObject任務

using BehaviorDesigner.Runtime;

using BehaviorDesigner.Runtime.Tasks;

using System.Collections;

using System.Collections.Generic;

using UnityEngine;

//用來判斷目標是否在視野內

public class MyCanSeeObject : Conditional {

public Transform[] targets;//判斷是否在視野內的目標

public float fildOfViewAngle = 90;

public float viewDistance = 7;

//行為樹局部Transform變量

public SharedTransform tagret;

public override TaskStatus OnUpdate()

{

if (targets==null) return TaskStatus.Failure;

foreach (var target in targets)

{

float distance = (target.position - transform.position).magnitude;

float angle = Vector3.Angle(transform.forward, target.position - transform.position);

if (distance

this.tagret.Value = target;

return TaskStatus.Success;

}

}

return TaskStatus.Failure;

}

}

Paste_Image.png

自寫一個追擊敵人的行為任務

using BehaviorDesigner.Runtime;

using BehaviorDesigner.Runtime.Tasks;

using System.Collections;

using System.Collections.Generic;

using UnityEngine;

using UnityEngine.AI;

//用來追敵人直到敵人跑出視野范圍外面

public class Defend : Action{

public SharedFloat viewDistance;

public SharedFloat fieldOfViewAngle;

public SharedFloat Speed;

public SharedFloat AngularSpeed;

public SharedTransform target;//要防御的目標

private float sqrViewDistance;

private NavMeshAgent navmeshAgent;

public override void OnAwake()

{

navmeshAgent = GetComponent();

}

public override void OnStart()

{

sqrViewDistance = viewDistance.Value * viewDistance.Value;

navmeshAgent.enabled = true;

navmeshAgent.speed = Speed.Value;

navmeshAgent.angularSpeed = AngularSpeed.Value;

navmeshAgent.destination = target.Value.position;

}

public override void OnEnd()

{

navmeshAgent.enabled = false;

}

//如果搶奪者在視野內,就追,否則就認為防御成功

public override TaskStatus OnUpdate()

{

if (target==null&&target.Value==null) {

return TaskStatus.Failure;

}

float sqrDistance = (target.Value.position - transform.position).sqrMagnitude;

float angle = Vector3.Angle(transform.forward, target.Value.position - transform.position);

if (sqrDistance

if (navmeshAgent.destination!=target.Value.position) {

navmeshAgent.destination = target.Value.position;

}

return TaskStatus.Running;

}

return TaskStatus.Success;

}

}

行為樹局部變量與全局變量

Paste_Image.png

//行為樹局部變量,后面必須.Value才能獲取到(target.Value.position)

public SharedTransform target;

//行為樹全局變量

public BehaviorTree behaviortree;

//設置與獲取全局變量

behaviortree.SetVariable("MyVariable", target);

behaviortree.GetVariable("MyVariable");

某些任務的含義

Paste_Image.png

Paste_Image.png

多個行為樹的使用

一個游戲對象可以使用多個行為樹。可相互切換行為樹的執行

private static CTFGameMenager _instance;

public static CTFGameMenager Instance {

get{

return _instance;

}

}

private List flagNotTakenBehaviorTrees=new List();

private List flagTakenBehaviorTrees=new List();

private void Awake()

{

_instance = this;

}

private void Start()

{

BehaviorTree[] bts= FindObjectsOfType();

foreach (var bt in bts)

{

if (bt.Group == 1) {//可根據行為樹的Group來查找需要的行為樹

flagNotTakenBehaviorTrees.Add(bt);

} else {

flagTakenBehaviorTrees.Add(bt);

}

}

}

//拿到旗幟

public void TakeFlag() {

foreach (var bt in flagNotTakenBehaviorTrees) {

if (BehaviorManager.instance.IsBehaviorEnabled(bt)) {//判斷行為樹是否啟用

bt.DisableBehavior();//禁用自身的行為樹

}

}

foreach (var bt in flagTakenBehaviorTrees)

{

if (BehaviorManager.instance.IsBehaviorEnabled(bt)==false) {

bt.EnableBehavior();//啟用自身的行為樹

}

}

}

//丟下旗幟

public void DropFlag() {

foreach (var bt in flagNotTakenBehaviorTrees)

{

if (BehaviorManager.instance.IsBehaviorEnabled(bt)==false)

{//判斷行為樹是否啟用

bt.EnableBehavior();//啟用自身

}

}

foreach (var bt in flagTakenBehaviorTrees)

{

if (BehaviorManager.instance.IsBehaviorEnabled(bt))

{

bt.DisableBehavior();//啟用自身

}

}

}

總結

以上是生活随笔為你收集整理的怪物行为树案例_Behavior Designer行为树(简单实现巡逻)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。