2024-07-23 Unity AI行为树2 —— 项目介绍

蔗理苦 2024-07-27 15:31:01 阅读 54

文章目录

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 目标。

image-20240723173801748

​ 项目地址:https://github.com/zheliku/BehaviourTree_AI。

2 AI 代码介绍

2.1 BTBaseNode / BTControlNode

​ 所有结点都需要执行各自的任务,因此提取到基类节点中:

<code>/// <summary>

/// 行为树结点基类

/// </summary>

public abstract class BTBaseNode

{

/// <summary>

/// 执行节点逻辑的抽象方法

/// </summary>

public abstract ENodeState Execute();

}

​ 而控制节点需要知道其控制哪些节点,因此相关内容需要提取到控制节点的基类中:

using System.Collections.Generic;

public abstract class BTControlNode : BTBaseNode

{

// 存储子节点的 List

protected List<BTBaseNode> _childList = new List<BTBaseNode>();

protected int _currentIndex = 0; // 当前执行到的子节点索引

/// <summary>

/// 添加子节点

/// </summary>

public virtual void AddChild(params BTBaseNode[] node) {

_childList.AddRange(node);

}

}

2.2 动作/条件节点

​ 动作节点执行具体的行为,没有子节点。

​ 执行完行为后,可以返回是否执行成功,因此需要外部添加执行的方法。

using System;

/// <summary>

/// 动作节点,执行具体行为,没有子节点

/// </summary>

public class BTActionNode : BTBaseNode

{

private Func<bool> _action; // 返回值表示执行是否成功

public BTActionNode(Func<bool> 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 Func<bool> _action; // 返回值表示执行是否成功

public BTConditionNode(Func<bool> 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 类图

BehaviourTree_AI



声明

本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。