怪物行为树案例_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行为树(简单实现巡逻)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: plsqlfor循环输出三角形_gliu
- 下一篇: python字典下标是什么_python