网站做锚点,wordpress 公司网站,大连网站推广怎么收费,赤峰建设业协会的官方网站文章目录 1 项目介绍2 AI 代码介绍2.1 BTBaseNode / BTControlNode2.2 动作/条件节点2.3 选择 / 顺序节点 3 怪物实现4 其他功能5 UML 类图 项目借鉴 B 站唐老狮 2023年直播内容。
点击前往唐老狮 B 站主页。 1 项目介绍
本项目使用 Unity 2022.3.32f1c1#xff0c;实现基… 文章目录 1 项目介绍2 AI 代码介绍2.1 BTBaseNode / BTControlNode2.2 动作/条件节点2.3 选择 / 顺序节点 3 怪物实现4 其他功能5 UML 类图 项目借鉴 B 站唐老狮 2023年直播内容。
点击前往唐老狮 B 站主页。 1 项目介绍
本项目使用 Unity 2022.3.32f1c1实现基本的 AI 框架。其中用 Cube红色代替怪物模型Cube蓝色代替玩家即 AI 目标。 项目地址https://github.com/zheliku/BehaviourTree_AI。
2 AI 代码介绍
2.1 BTBaseNode / BTControlNode
所有结点都需要执行各自的任务因此提取到基类节点中
/// summary
/// 行为树结点基类
/// /summary
public abstract class BTBaseNode
{/// summary/// 执行节点逻辑的抽象方法/// /summarypublic abstract ENodeState Execute();
} 而控制节点需要知道其控制哪些节点因此相关内容需要提取到控制节点的基类中
using System.Collections.Generic;public abstract class BTControlNode : BTBaseNode
{// 存储子节点的 Listprotected ListBTBaseNode _childList new ListBTBaseNode();protected int _currentIndex 0; // 当前执行到的子节点索引/// summary/// 添加子节点/// /summarypublic virtual void AddChild(params BTBaseNode[] node) {_childList.AddRange(node);}
}2.2 动作/条件节点
动作节点执行具体的行为没有子节点。
执行完行为后可以返回是否执行成功因此需要外部添加执行的方法。
using System;/// summary
/// 动作节点执行具体行为没有子节点
/// /summary
public class BTActionNode : BTBaseNode
{private Funcbool _action; // 返回值表示执行是否成功public BTActionNode(Funcbool action) { _action action; }public override ENodeState Execute() {if (_action null) return ENodeState.Failure;// 执行行为return _action.Invoke() ? ENodeState.Success : ENodeState.Failure; }
} 条件节点用于评估条件根据条件结果返回成功 / 失败。
和动作节点类似也需要外部提供判断条件的方法。
using System;/// summary
/// 条件节点评估一个条件并返回成功 / 失败
/// /summary
public class BTConditionNode : BTBaseNode
{private Funcbool _action; // 返回值表示执行是否成功public BTConditionNode(Funcbool action) { _action action; }public override ENodeState Execute() {if (_action null) return ENodeState.Failure;// 执行行为return _action.Invoke() ? ENodeState.Success : ENodeState.Failure; }
}2.3 选择 / 顺序节点
选择 / 顺序节点都仅依据子节点的状态返回自己的状态。因此只需要实现 Execute() 方法即可区别在于实现的逻辑不同。
using System;/// summary
/// 选择节点br/
/// 特点br/
/// 1. 按顺序执行子节点br/
/// 2. 如果某子节点返回成功则返回成功不执行后续结点br/
/// 3. 如果某子节点返回失败则继续执行下一个子节点
/// /summary
public class BTSelectNode : BTControlNode
{public override ENodeState Execute() {var childNode _childList[_currentIndex];var result childNode.Execute();switch (result) {case ENodeState.Success: { // 成功则重置索引直接返回_currentIndex 0;return ENodeState.Success;}case ENodeState.Failure: { // 失败则继续下一个节点_currentIndex;if (_currentIndex _childList.Count) { // 执行到最后重置索引_currentIndex 0;return ENodeState.Failure;}break;}case ENodeState.Running: {return ENodeState.Running;}default: throw new ArgumentOutOfRangeException();}// 没有执行完或者节点失败才执行该逻辑// 此时仍希望下一帧继续往后执行因此返回成功return ENodeState.Success;}
}/// summary
/// 序列节点br/
/// 特点br/
/// 1. 按顺序执行子节点br/
/// 2. 只要有一个子节点返回失败则整个节点返回失败br/
/// 3. 所有子节点都返回成功则整个节点返回成功
/// /summary
public class BTSequenceNode : BTControlNode
{public override ENodeState Execute() {var childNode _childList[_currentIndex];var result childNode.Execute();switch (result) {case ENodeState.Success: { // 成功则继续下一个节点_currentIndex;if (_currentIndex _childList.Count) { // 执行到最后重置索引_currentIndex 0;return ENodeState.Success;}break;}case ENodeState.Failure: { // 失败则重置索引直接返回_currentIndex 0;return ENodeState.Failure;}case ENodeState.Running: {return ENodeState.Running;}default: throw new ArgumentOutOfRangeException();}return ENodeState.Success;}
}3 怪物实现
类似 2024-07-12 Unity AI状态机1 —— 框架介绍_有限状态机编程框架-CSDN博客 中的怪物实现但将怪物数据写在各个行为的控制类中因此具有以下 4 个控制类
PatrolControl巡逻ChaseControl追逐AttackControl攻击BackControl返回
其余实现基本一致。
4 其他功能
为了辅助绘图在 Monster 类中的 Update 方法里判断当前执行的行为 / 状态。用二进制位表示每个状态异或运算来计算当前的状态
private void Update() {_btAIRoot.Execute(); // 执行行为树switch (CurrentState) { // 依据当前行为绘制辅助线case 1:AttackCtrl.DrawGizmos();break;case 2:BackCtrl.DrawGizmos();break;case 4:ChaseCtrl.DrawGizmos();break;case 8:PatrolCtrl.DrawGizmos();break;}
}5 UML 类图