Behavior Designer行為樹(簡單實現(xiàn)巡邏)

做一個簡單敵人巡邏

導(dǎo)入資源后权悟,直接添加一個Tasks-> Actions->Patrol行為樹任務(wù)


Paste_Image.png

然后進入Inspector設(shè)置參數(shù)


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

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


Paste_Image.png

35分10秒.gif
會追擊所看到的敵人

下面是設(shè)置行為樹的執(zhí)行關(guān)系


Paste_Image.png

首先我們設(shè)置三個變量鹰霍,一個是游戲?qū)ο蟮乃俣?旋轉(zhuǎn)速度和所要追擊敵人的Transform挖炬。


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

下面我們設(shè)置看到目標敵人后就需要去追擊敵人逼庞。所以Target Transform就要設(shè)置敵人的Transform宵晚。


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

Paste_Image.png

Paste_Image.png

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

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


Paste_Image.png
自寫Seek任務(wù)

直接讓它繼承自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;
    }
    //當進入到這個任務(wù)的時候,會一直調(diào)用這個方法睁搭,一直到任務(wù)結(jié)束  一返回一個 成功或者失敗的狀態(tài) 
    //那么認為結(jié)束  如果返回一個running的狀態(tài)赶诊,那這個方法會繼續(xù)被調(diào)用
    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<sqrArriveDistance) {
            return TaskStatus.Success;//如果距離目標位置的距離比較小,認為達到目標文字园骆,直接Return成功
        }
        return TaskStatus.Running;
    }
}


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

Paste_Image.png
自寫CanSeekObject任務(wù)
using BehaviorDesigner.Runtime;
using BehaviorDesigner.Runtime.Tasks;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

//用來判斷目標是否在視野內(nèi)
public class MyCanSeeObject : Conditional {
    public Transform[] targets;//判斷是否在視野內(nèi)的目標

    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<viewDistance&&angle< fildOfViewAngle*0.5f) {
                this.tagret.Value = target;
                return TaskStatus.Success;
            }
        }
        return TaskStatus.Failure;
    }    
}

Paste_Image.png
自寫一個追擊敵人的行為任務(wù)
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<NavMeshAgent>();
    }
    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;
    }
    //如果搶奪者在視野內(nèi)舔痪,就追,否則就認為防御成功
    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<sqrViewDistance&&angle<fieldOfViewAngle.Value*0.5f) {
            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;
       //設(shè)置與獲取全局變量
       behaviortree.SetVariable("MyVariable", target);
        behaviortree.GetVariable("MyVariable");

某些任務(wù)的含義
Paste_Image.png

Paste_Image.png
多個行為樹的使用

一個游戲?qū)ο罂梢允褂枚鄠€行為樹辙喂。可相互切換行為樹的執(zhí)行

  private static CTFGameMenager _instance;

    public static CTFGameMenager Instance {
        get{
            return _instance;
        }
    }

    private List<BehaviorTree> flagNotTakenBehaviorTrees=new List<BehaviorTree>();
    private List<BehaviorTree> flagTakenBehaviorTrees=new List<BehaviorTree>();

    private void Awake()
    {
        _instance = this;
    }
    private void Start()
    {
      BehaviorTree[] bts=  FindObjectsOfType<BehaviorTree>();
        foreach (var bt in bts)
        {
            if (bt.Group == 1) {//可根據(jù)行為樹的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();//啟用自身
            }
        }
    }
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末鸠珠,一起剝皮案震驚了整個濱河市巍耗,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌渐排,老刑警劉巖炬太,帶你破解...
    沈念sama閱讀 212,542評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異驯耻,居然都是意外死亡亲族,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,596評論 3 385
  • 文/潘曉璐 我一進店門可缚,熙熙樓的掌柜王于貴愁眉苦臉地迎上來霎迫,“玉大人,你說我怎么就攤上這事帘靡≈” “怎么了?”我有些...
    開封第一講書人閱讀 158,021評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長涩赢。 經(jīng)常有香客問我戈次,道長,這世上最難降的妖魔是什么筒扒? 我笑而不...
    開封第一講書人閱讀 56,682評論 1 284
  • 正文 為了忘掉前任怯邪,我火速辦了婚禮,結(jié)果婚禮上花墩,老公的妹妹穿的比我還像新娘悬秉。我一直安慰自己,他們只是感情好观游,可當我...
    茶點故事閱讀 65,792評論 6 386
  • 文/花漫 我一把揭開白布搂捧。 她就那樣靜靜地躺著,像睡著了一般懂缕。 火紅的嫁衣襯著肌膚如雪允跑。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,985評論 1 291
  • 那天搪柑,我揣著相機與錄音聋丝,去河邊找鬼。 笑死工碾,一個胖子當著我的面吹牛弱睦,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播渊额,決...
    沈念sama閱讀 39,107評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼况木,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了旬迹?” 一聲冷哼從身側(cè)響起火惊,我...
    開封第一講書人閱讀 37,845評論 0 268
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎奔垦,沒想到半個月后屹耐,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,299評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡椿猎,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,612評論 2 327
  • 正文 我和宋清朗相戀三年惶岭,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片犯眠。...
    茶點故事閱讀 38,747評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡按灶,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出筐咧,到底是詐尸還是另有隱情鸯旁,我是刑警寧澤,帶...
    沈念sama閱讀 34,441評論 4 333
  • 正文 年R本政府宣布,位于F島的核電站羡亩,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏危融。R本人自食惡果不足惜畏铆,卻給世界環(huán)境...
    茶點故事閱讀 40,072評論 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望吉殃。 院中可真熱鬧辞居,春花似錦、人聲如沸蛋勺。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,828評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽抱完。三九已至贼陶,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間巧娱,已是汗流浹背碉怔。 一陣腳步聲響...
    開封第一講書人閱讀 32,069評論 1 267
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留禁添,地道東北人撮胧。 一個月前我還...
    沈念sama閱讀 46,545評論 2 362
  • 正文 我出身青樓,卻偏偏與公主長得像老翘,于是被迫代替她去往敵國和親芹啥。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,658評論 2 350

推薦閱讀更多精彩內(nèi)容

  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法铺峭,類相關(guān)的語法墓怀,內(nèi)部類的語法,繼承相關(guān)的語法逛薇,異常的語法捺疼,線程的語...
    子非魚_t_閱讀 31,602評論 18 399
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn)永罚,斷路器啤呼,智...
    卡卡羅2017閱讀 134,637評論 18 139
  • Behavior Designer 概述 第一部分是主要的設(shè)計工作的區(qū)域!在這個區(qū)域呢袱,你可以創(chuàng)建新的 Task(任...
    JumboWu閱讀 48,476評論 5 57
  • 高速公路大隊2018年1月4日工作開展情況: 一官扣、勤務(wù)情況:出動警力10人,警車2輛羞福。 二惕蹄、道路交通事故:簡易事故...
    吾愛軒寶閱讀 243評論 0 0
  • (原創(chuàng))柳漫軒 小騰和小靜是大學(xué)同學(xué)卖陵,從進校園第一年就成為彼此的初戀遭顶。 小騰長得斯斯文文,戴一副眼鏡泪蔫,讀的是理科棒旗,...
    軒兒柳漫軒閱讀 562評論 0 1