怪物行为树案例_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行为树(简单实现巡逻)相关推荐
- Unity3D Behavior Designer 行为树1 认识
环境:Unity2017.4 语言:C# 总起: 行为树,我很早就了解到了这个插件,不过对于它究竟是什么其实概念上比较模糊,这次正好趁机我们一起来学习一下(跟渲染一样AI也是个大坑). 本次教程基于插 ...
- 基于python win32com的visio文件基础操作语句简介及案例展示(家族树自动创建)
1 写在前面 最近需要给老师们做家族树,向visio模板中套excel数据,但是在手动套模板的过程中发现间距的控制是一个较为繁琐的事情,于是萌生了用python完成这一过程的想法. 在探索的过程中经验 ...
- class4 决策树之回归树案例
part1 案例: 用回归树来拟合一条曲线,添加噪声来观察回归树的表现 # (1)导入库 import numpy as np # 生成正弦曲线上的点 from sklearn.tree import ...
- python梯度提升回归树_梯度提升回归树(GBDT)
梯度提升回归树(GBDT) 发布时间:2018-08-30 13:22, 浏览次数:1024 , 标签: GBDT 一.从Boosting思想开始 1.梯度提升回归树是一种从它的错误中进行学习的技术. ...
- AcWing 蓝桥杯AB组辅导课 05、树状数组与线段树
文章目录 前言 一.树状数组 1.1.树状数组知识点 1.2.树状数组代码模板 模板题:AcWing 1264. 动态求连续区间和 例题 例题1.AcWing 1265. 数星星[中等,信息学奥赛一本 ...
- 数据结构与算法(6-1)树的存储(树的双亲表示、树的孩子表示及树的双亲孩子表示)
目录 一.树的双亲表示 存储结构 总代码 二.树的孩子表示 存储结构 总代码 三.树的双亲孩子表示 存储结构 一.树的双亲表示 存储结构 采用结构体数组的形式存储数据. (根结点parent=1:它没 ...
- 赫夫曼树(哈夫曼树)
赫夫曼树->赫夫曼编码 在数据膨胀.信息爆炸的今天,数据压缩的意义不言而喻. 一个字节8位 赫夫曼编码压缩-无损压缩 可以看成成绩的排布.成绩是70-90之间占有70%,所以以下两个数据结构优化 ...
- 树套树 ----- P1975 [国家集训队]排队(树状数组套权值线段树求动态逆序对)
解题思路: 首先我们知道交换两个数a[l]和a[r]a[l]和a[r]a[l]和a[r]影响到的区间是[l+1,r−1][l+1,r-1][l+1,r−1] 对于a[l]a[l]a[l],我们要减去[ ...
- szu 寒训第二天 树状数组 二维树状数组详解,以及树状数组扩展应用【求逆序对,以及动态第k小数】
树状数组(Binary Index Tree) 树状数组可以解决可以转化为前缀和问题的问题 这是一类用以解决动态前缀和的问题 (有点像线段树简版) 1.对于 a1 + a2 + a3 + - + an ...
最新文章
- 【学习笔记】超简单的快速傅里叶变换(FFT)(含全套证明)
- X5本地应用打包服务器环境搭建
- poj 3026 (最小生成树)
- html5实例异步图片加载,javascript – 你如何处理html5的画布图像加载异步?
- 计算机网络英文介绍,计算机网络英文自我介绍
- Abp vnext Web应用程序开发教程 7 —— 作者:数据库集成
- 电池图标不见了怎么解决
- dorado 刷新_dorado BDF常见问题
- 洛谷 P1993 小K的农场 解题报告
- 机器学习——k近邻算法
- 【OpenCV】Rect函数
- 在线Word文档怎么做—使用超级文档一站式解决
- 解决外接显示屏耳机没声音问题
- everedit 格式化json_Visual studio code (VS code)
- netlogon启动后停止_【漏洞通报】微软NetLogon提权漏洞
- IT运维服务外包管理的两种模式
- Unity KeyCode键值
- 平台设备platform_device和平台驱动platform_driver
- 一种基于中继模式的跨链通信方案
- 上拉电阻的作用与计算
热门文章
- pythonsqlite视图_SQLite VIEW/视图
- 试用c51语言采样连续5次异常_浙江省动态血压监测操作及诊断规范(试用版)
- git 添加用户名和邮箱_设置 Git 账户及邮箱
- as my sql 后面加表达式_Lambda 表达式有何用处?如何使用?
- 该页面仅以HTML格式保存_第七节:框架搭建之页面静态化的剖析
- 在没有任何数据时进行无效的读取尝试。_技术转载——JVM运行时内存是怎么分布的?...
- mysql字段名explain_Mysql中explain用法和结果字段的含义介绍
- 利用Selenium爬取淘宝商品信息
- JSON数据格式:以及XML文件格式,YML文件格式,properties文件格式
- Software--Architecture--Design