第七章 行为树技术在游戏AI复杂决策中的应用

7.1 行为树系统的基本原理与架构设计

7.1.1 行为树核心概念解析

行为树(Behavior Tree)是游戏AI领域中用于构建复杂决策系统的树状结构模型。与有限状态机相比,行为树提供了更直观、更模块化的方式来组织和控制AI行为。行为树通过节点之间的层次关系和执行流程来定义AI的决策逻辑,每个节点都有特定的功能和执行结果。

行为树的核心优势在于:

  • 模块化设计:行为可以分解为可重用的子任务
  • 可读性强:树状结构直观展示AI决策流程
  • 灵活扩展:容易添加新的行为而不影响现有逻辑
  • 并行处理:支持多个行为同时执行
  • 易于调试:可以可视化追踪行为执行路径

下面是行为树系统的基础架构实现:

using UnityEngine;
using System;
using System.Collections;
using System.Collections.Generic;

namespace BehaviorTreeSystem
{
    /// <summary>
    /// 节点执行状态
    /// </summary>
    public enum NodeStatus
    {
        Success,    // 成功
        Failure,    // 失败
        Running     // 执行中
    }

    /// <summary>
    /// 行为树节点基类
    /// </summary>
    public abstract class BTNode
    {
        protected string nodeName;
        protected BehaviorTree behaviorTree;
        protected Blackboard blackboard;
        
        public string NodeName 
        { 
            get { return nodeName; } 
        }
        
        public BTNode(string name)
        {
            nodeName = name;
        }
        
        public virtual void Initialize(BehaviorTree tree, Blackboard bb)
        {
            behaviorTree = tree;
            blackboard = bb;
        }
        
        public abstract NodeStatus Evaluate();
        public virtual void OnEnter() { }
        public virtual void OnExit() { }
        public virtual void OnReset() { }
        public virtual void OnAbort() { }
    }

    /// <summary>
    /// 行为树
    /// </summary>
    public class BehaviorTree
    {
        private BTNode rootNode;
        private Blackboard blackboard;
        private GameObject owner;
        private BTNode currentRunningNode;
        private List<BTNode> nodeHistory;
        private bool isRunning;
        private bool isPaused;
        private int maxHistorySize = 100;
        
        public GameObject Owner 
        { 
            get { return owner; } 
        }
        
        public Blackboard Blackboard 
        { 
            get { return blackboard; } 
        }
        
        public bool IsRunning 
        { 
            get { return isRunning; } 
        }
        
        public event Action<string, NodeStatus> OnNodeExecuted;
        public event Action<string> OnTreeStarted;
        public event Action<string> OnTreeStopped;
        public event Action<string, string> OnNodeChanged;
        
        public BehaviorTree(GameObject owner, BTNode root, Blackboard bb = null)
        {
            this.owner = owner;
            rootNode = root;
            blackboard = bb ?? new Blackboard();
            nodeHistory = new List<BTNode>();
            
            // 初始化根节点
            rootNode.Initialize(this, blackboard);
        }
        
        public void Start()
        {
            if (isRunning)
            {
                Debug.LogWarning("行为树已经在运行");
                return;
            }
            
            isRunning = true;
            isPaused = false;
            nodeHistory.Clear();
            
            OnTreeStarted?.Invoke(owner.name);
            
            Debug.Log($"行为树开始执行: {owner.name}");
        }
        
        public void Stop()
        {
            if (!isRunning)
            {
                return;
            }
            
            isRunning = false;
            
            // 中止当前运行节点
            if (currentRunningNode != null)
            {
                currentRunningNode.OnAbort();
                currentRunningNode = null;
            }
            
            // 重置所有节点
            ResetTree();
            
            OnTreeStopped?.Invoke(owner.name);
            
            Debug.Log($"行为树停止执行: {owner.name}");
        }
        
        public void Pause()
        {
            if (!isRunning || isPaused)
            {
                return;
            }
            
            isPaused = true;
            
            if (currentRunningNode != null)
            {
                currentRunningNode.OnAbort();
            }
            
            Debug.Log($"行为树暂停: {owner.name}");
        }
        
        public void Resume()
        {
            if (!isRunning || !isPaused)
            {
                return;
            }
            
            isPaused = false;
            
            Debug.Log($"行为树恢复执行: {owner.name}");
        }
        
        public void Update()
        {
            if (!isRunning || isPaused)
            {
                return;
            }
            
            if (rootNode == null)
            {
                Debug.LogError("行为树没有根节点");
                return;
            }
            
            // 执行根节点
            NodeStatus status = rootNode.Evaluate();
            
            // 记录执行状态
            if (status != NodeStatus.Running)
            {
                // 非运行状态表示树执行完成
                // 在实际应用中,行为树通常持续运行,这里可以根据需要处理
            }
        }
        
        public void SetRunningNode(BTNode node)
        {
            BTNode previousNode = currentRunningNode;
            currentRunningNode = node;
            
            OnNodeChanged?.Invoke(
                previousNode?.NodeName ?? "None", 
                node?.NodeName ?? "None"
            );
        }
        
        public void RecordNodeExecution(BTNode node, NodeStatus status)
        {
            // 记录节点执行历史
            nodeHistory.Add(node);
            
            // 限制历史记录大小
            if (nodeHistory.Count > maxHistorySize)
            {
                nodeHistory.RemoveAt(0);
            }
            
            OnNodeExecuted?.Invoke(node.NodeName, status);
        }
        
        private void ResetTree()
        {
            // 递归重置所有节点
            ResetNode(rootNode);
        }
        
        private void ResetNode(BTNode node)
        {
            if (node == null)
            {
                return;
            }
            
            node.OnReset();
            
            // 如果是组合节点,递归重置子节点
            if (node is CompositeNode composite)
            {
                foreach (BTNode child in composite.GetChildren())
                {
                    ResetNode(child);
                }
            }
            // 如果是装饰节点,重置子节点
            else if (node is DecoratorNode decorator)
            {
                if (decorator.HasChild())
                {
                    ResetNode(decorator.GetChild());
                }
            }
        }
        
        public List<string> GetExecutionHistory(int count = 20)
        {
            List<string> history = new List<string>();
            int startIndex = Mathf.Max(0, nodeHistory.Count - count);
            
            for (int i = startIndex; i < nodeHistory.Count; i++)
            {
                history.Add(nodeHistory[i].NodeName);
            }
            
            return history;
        }
        
        public BTNode FindNode(string nodeName)
        {
            return FindNodeRecursive(rootNode, nodeName);
        }
        
        private BTNode FindNodeRecursive(BTNode node, string nodeName)
        {
            if (node == null)
            {
                return null;
            }
            
            if (node.NodeName == nodeName)
            {
                return node;
            }
            
            if (node is CompositeNode composite)
            {
                foreach (BTNode child in composite.GetChildren())
                {
                    BTNode found = FindNodeRecursive(child, nodeName);
                    if (found != null)
                    {
                        return found;
                    }
                }
            }
            else if (node is DecoratorNode decorator && decorator.HasChild())
            {
                return FindNodeRecursive(decorator.GetChild(), nodeName);
            }
            
            return null;
        }
    }

    /// <summary>
    /// 黑板系统 - 用于节点间数据共享
    /// </summary>
    public class Blackboard
    {
        private Dictionary<string, object> data;
        private Dictionary<string, List<Action<object>>> listeners;
        
        public Blackboard()
        {
            data = new Dictionary<string, object>();
            listeners = new Dictionary<string, List<Action<object>>>();
        }
        
        public void SetValue<T>(string key, T value)
        {
            data[key] = value;
            
            // 通知监听者
            if (listeners.ContainsKey(key))
            {
                foreach (Action<object> listener in listeners[key])
                {
                    listener(value);
                }
            }
        }
        
        public T GetValue<T>(string key, T defaultValue = default(T))
        {
            if (data.ContainsKey(key) && data[key] is T)
            {
                return (T)data[key];
            }
            return defaultValue;
        }
        
        public bool HasValue(string key)
        {
            return data.ContainsKey(key);
        }
        
        public void RemoveValue(string key)
        {
            if (data.ContainsKey(key))
            {
                data.Remove(key);
            }
        }
        
        public void AddListener(string key, Action<object> listener)
        {
            if (!listeners.ContainsKey(key))
            {
                listeners[key] = new List<Action<object>>();
            }
            
            if (!listeners[key].Contains(listener))
            {
                listeners[key].Add(listener);
            }
        }
        
        public void RemoveListener(string key, Action<object> listener)
        {
            if (listeners.ContainsKey(key))
            {
                listeners[key].Remove(listener);
            }
        }
        
        public void Clear()
        {
            data.Clear();
            listeners.Clear();
        }
        
        public Dictionary<string, object> GetAllData()
        {
            return new Dictionary<string, object>(data);
        }
    }
}

7.1.2 叶节点:行为与条件的实现

叶节点是行为树的终端节点,负责执行具体的任务或检查条件。叶节点分为两种类型:动作节点(Action Node)和条件节点(Condition Node)。动作节点执行具体行为,如移动、攻击等;条件节点检查特定条件并返回成功或失败。

下面是叶节点的具体实现:

namespace BehaviorTreeSystem
{
    /// <summary>
    /// 动作节点基类 - 执行具体行为
    /// </summary>
    public abstract class ActionNode : BTNode
    {
        protected float executionTime;
        protected float startTime;
        protected bool isRunning;
        
        public ActionNode(string name) : base(name)
        {
            executionTime = 0f;
            isRunning = false;
        }
        
        public override void OnEnter()
        {
            startTime = Time.time;
            isRunning = true;
            
            Debug.Log($"动作节点进入: {nodeName}");
        }
        
        public override void OnExit()
        {
            isRunning = false;
            executionTime = Time.time - startTime;
            
            Debug.Log($"动作节点退出: {nodeName},执行时间: {executionTime:F2}s");
        }
        
        public override void OnReset()
        {
            isRunning = false;
            executionTime = 0f;
        }
        
        public override void OnAbort()
        {
            if (isRunning)
            {
                OnExit();
            }
        }
        
        public abstract NodeStatus Execute();
        
        public override NodeStatus Evaluate()
        {
            if (!isRunning)
            {
                OnEnter();
            }
            
            NodeStatus status = Execute();
            
            if (status != NodeStatus.Running)
            {
                OnExit();
                behaviorTree.SetRunningNode(null);
            }
            else
            {
                behaviorTree.SetRunningNode(this);
            }
            
            behaviorTree.RecordNodeExecution(this, status);
            return status;
        }
    }
    
    /// <summary>
    /// 条件节点基类 - 检查条件
    /// </summary>
    public abstract class ConditionNode : BTNode
    {
        public ConditionNode(string name) : base(name) { }
        
        public abstract bool CheckCondition();
        
        public override NodeStatus Evaluate()
        {
            bool conditionMet = CheckCondition();
            NodeStatus status = conditionMet ? NodeStatus.Success : NodeStatus.Failure;
            
            behaviorTree.RecordNodeExecution(this, status);
            return status;
        }
    }
    
    /// <summary>
    /// 组合节点基类 - 管理子节点
    /// </summary>
    public abstract class CompositeNode : BTNode
    {
        protected List<BTNode> children;
        protected int currentChildIndex;
        
        public CompositeNode(string name) : base(name)
        {
            children = new List<BTNode>();
            currentChildIndex = 0;
        }
        
        public void AddChild(BTNode child)
        {
            if (child != null)
            {
                children.Add(child);
                child.Initialize(behaviorTree, blackboard);
            }
        }
        
        public void RemoveChild(BTNode child)
        {
            if (children.Contains(child))
            {
                children.Remove(child);
            }
        }
        
        public void RemoveChildAt(int index)
        {
            if (index >= 0 && index < children.Count)
            {
                children.RemoveAt(index);
            }
        }
        
        public BTNode GetChild(int index)
        {
            if (index >= 0 && index < children.Count)
            {
                return children[index];
            }
            return null;
        }
        
        public List<BTNode> GetChildren()
        {
            return new List<BTNode>(children);
        }
        
        public int ChildCount
        {
            get { return children.Count; }
        }
        
        public override void OnReset()
        {
            currentChildIndex = 0;
            
            foreach (BTNode child in children)
            {
                child.OnReset();
            }
        }
        
        public override void OnAbort()
        {
            // 中止当前执行的子节点
            if (currentChildIndex < children.Count)
            {
                children[currentChildIndex].OnAbort();
            }
        }
    }
    
    /// <summary>
    /// 顺序节点 - 按顺序执行子节点,所有成功则成功,任何一个失败则失败
    /// </summary>
    public class SequenceNode : CompositeNode
    {
        public SequenceNode(string name) : base(name) { }
        
        public override NodeStatus Evaluate()
        {
            if (children.Count == 0)
            {
                return NodeStatus.Failure;
            }
            
            // 从当前索引开始执行
            while (currentChildIndex < children.Count)
            {
                BTNode child = children[currentChildIndex];
                NodeStatus status = child.Evaluate();
                
                if (status == NodeStatus.Running)
                {
                    behaviorTree.SetRunningNode(this);
                    return NodeStatus.Running;
                }
                else if (status == NodeStatus.Failure)
                {
                    // 失败则重置并返回失败
                    currentChildIndex = 0;
                    behaviorTree.SetRunningNode(null);
                    return NodeStatus.Failure;
                }
                else if (status == NodeStatus.Success)
                {
                    // 成功则继续下一个子节点
                    currentChildIndex++;
                }
            }
            
            // 所有子节点执行成功
            currentChildIndex = 0;
            behaviorTree.SetRunningNode(null);
            return NodeStatus.Success;
        }
    }
    
    /// <summary>
    /// 选择节点(Fallback) - 执行子节点直到一个成功,所有失败则失败
    /// </summary>
    public class SelectorNode : CompositeNode
    {
        public SelectorNode(string name) : base(name) { }
        
        public override NodeStatus Evaluate()
        {
            if (children.Count == 0)
            {
                return NodeStatus.Failure;
            }
            
            // 从当前索引开始执行
            while (currentChildIndex < children.Count)
            {
                BTNode child = children[currentChildIndex];
                NodeStatus status = child.Evaluate();
                
                if (status == NodeStatus.Running)
                {
                    behaviorTree.SetRunningNode(this);
                    return NodeStatus.Running;
                }
                else if (status == NodeStatus.Success)
                {
                    // 成功则重置并返回成功
                    currentChildIndex = 0;
                    behaviorTree.SetRunningNode(null);
                    return NodeStatus.Success;
                }
                else if (status == NodeStatus.Failure)
                {
                    // 失败则继续下一个子节点
                    currentChildIndex++;
                }
            }
            
            // 所有子节点执行失败
            currentChildIndex = 0;
            behaviorTree.SetRunningNode(null);
            return NodeStatus.Failure;
        }
    }
    
    /// <summary>
    /// 并行节点 - 同时执行所有子节点
    /// </summary>
    public class ParallelNode : CompositeNode
    {
        public enum ParallelPolicy
        {
            AllSuccess,     // 所有子节点成功才算成功
            AllFailure,     // 所有子节点失败才算失败
            OneSuccess,     // 一个子节点成功就算成功
            OneFailure      // 一个子节点失败就算失败
        }
        
        private ParallelPolicy successPolicy;
        private ParallelPolicy failurePolicy;
        private Dictionary<BTNode, NodeStatus> childStatuses;
        
        public ParallelNode(string name, ParallelPolicy successPolicy = ParallelPolicy.AllSuccess, 
                          ParallelPolicy failurePolicy = ParallelPolicy.OneFailure) : base(name)
        {
            this.successPolicy = successPolicy;
            this.failurePolicy = failurePolicy;
            childStatuses = new Dictionary<BTNode, NodeStatus>();
        }
        
        public override void OnEnter()
        {
            base.OnEnter();
            
            // 初始化子节点状态
            childStatuses.Clear();
            foreach (BTNode child in children)
            {
                childStatuses[child] = NodeStatus.Running;
            }
        }
        
        public override NodeStatus Evaluate()
        {
            if (children.Count == 0)
            {
                return NodeStatus.Failure;
            }
            
            int successCount = 0;
            int failureCount = 0;
            int runningCount = 0;
            
            // 执行所有子节点
            foreach (BTNode child in children)
            {
                if (childStatuses[child] == NodeStatus.Running)
                {
                    NodeStatus status = child.Evaluate();
                    childStatuses[child] = status;
                }
                
                // 统计结果
                switch (childStatuses[child])
                {
                    case NodeStatus.Success:
                        successCount++;
                        break;
                    case NodeStatus.Failure:
                        failureCount++;
                        break;
                    case NodeStatus.Running:
                        runningCount++;
                        break;
                }
            }
            
            // 根据策略判断结果
            bool isSuccess = false;
            bool isFailure = false;
            
            switch (successPolicy)
            {
                case ParallelPolicy.AllSuccess:
                    isSuccess = (successCount == children.Count);
                    break;
                case ParallelPolicy.OneSuccess:
                    isSuccess = (successCount > 0);
                    break;
            }
            
            switch (failurePolicy)
            {
                case ParallelPolicy.AllFailure:
                    isFailure = (failureCount == children.Count);
                    break;
                case ParallelPolicy.OneFailure:
                    isFailure = (failureCount > 0);
                    break;
            }
            
            // 返回结果
            if (isSuccess)
            {
                behaviorTree.SetRunningNode(null);
                return NodeStatus.Success;
            }
            else if (isFailure)
            {
                behaviorTree.SetRunningNode(null);
                return NodeStatus.Failure;
            }
            else if (runningCount > 0)
            {
                behaviorTree.SetRunningNode(this);
                return NodeStatus.Running;
            }
            else
            {
                // 默认情况
                behaviorTree.SetRunningNode(null);
                return NodeStatus.Failure;
            }
        }
        
        public override void OnReset()
        {
            base.OnReset();
            childStatuses.Clear();
        }
    }
    
    /// <summary>
    /// 随机节点 - 随机选择一个子节点执行
    /// </summary>
    public class RandomNode : CompositeNode
    {
        private System.Random random;
        private int selectedChildIndex;
        private bool hasSelected;
        
        public RandomNode(string name, int seed = 0) : base(name)
        {
            random = seed == 0 ? new System.Random() : new System.Random(seed);
            selectedChildIndex = -1;
            hasSelected = false;
        }
        
        public override void OnEnter()
        {
            base.OnEnter();
            
            // 随机选择一个子节点
            if (children.Count > 0)
            {
                selectedChildIndex = random.Next(0, children.Count);
                hasSelected = true;
            }
            else
            {
                selectedChildIndex = -1;
                hasSelected = false;
            }
        }
        
        public override NodeStatus Evaluate()
        {
            if (children.Count == 0 || selectedChildIndex == -1)
            {
                return NodeStatus.Failure;
            }
            
            BTNode selectedChild = children[selectedChildIndex];
            NodeStatus status = selectedChild.Evaluate();
            
            if (status == NodeStatus.Running)
            {
                behaviorTree.SetRunningNode(this);
                return NodeStatus.Running;
            }
            else
            {
                // 执行完成,重置选择状态
                hasSelected = false;
                behaviorTree.SetRunningNode(null);
                return status;
            }
        }
        
        public override void OnReset()
        {
            base.OnReset();
            selectedChildIndex = -1;
            hasSelected = false;
        }
    }
}

7.1.3 装饰节点与组合节点的扩展实现

装饰节点用于修改或增强子节点的行为,它们只有一个子节点。装饰节点可以实现循环、限制、条件检查等功能。

namespace BehaviorTreeSystem
{
    /// <summary>
    /// 装饰节点基类 - 修饰单个子节点的行为
    /// </summary>
    public abstract class DecoratorNode : BTNode
    {
        protected BTNode child;
        
        public DecoratorNode(string name, BTNode child = null) : base(name)
        {
            this.child = child;
        }
        
        public void SetChild(BTNode newChild)
        {
            child = newChild;
            if (child != null && behaviorTree != null)
            {
                child.Initialize(behaviorTree, blackboard);
            }
        }
        
        public BTNode GetChild()
        {
            return child;
        }
        
        public bool HasChild()
        {
            return child != null;
        }
        
        public override void Initialize(BehaviorTree tree, Blackboard bb)
        {
            base.Initialize(tree, bb);
            
            if (child != null)
            {
                child.Initialize(tree, bb);
            }
        }
        
        public override void OnReset()
        {
            if (child != null)
            {
                child.OnReset();
            }
        }
        
        public override void OnAbort()
        {
            if (child != null)
            {
                child.OnAbort();
            }
        }
    }
    
    /// <summary>
    /// 逆变节点 - 反转子节点的执行结果
    /// </summary>
    public class InverterNode : DecoratorNode
    {
        public InverterNode(string name, BTNode child = null) : base(name, child) { }
        
        public override NodeStatus Evaluate()
        {
            if (child == null)
            {
                return NodeStatus.Failure;
            }
            
            NodeStatus status = child.Evaluate();
            
            switch (status)
            {
                case NodeStatus.Success:
                    return NodeStatus.Failure;
                case NodeStatus.Failure:
                    return NodeStatus.Success;
                case NodeStatus.Running:
                    return NodeStatus.Running;
                default:
                    return NodeStatus.Failure;
            }
        }
    }
    
    /// <summary>
    /// 重复节点 - 重复执行子节点指定次数或无限重复
    /// </summary>
    public class RepeaterNode : DecoratorNode
    {
        private int repeatCount;
        private int currentCount;
        private bool infinite;
        
        public RepeaterNode(string name, int repeatCount = -1, BTNode child = null) : base(name, child)
        {
            this.repeatCount = repeatCount;
            currentCount = 0;
            infinite = repeatCount < 0;
        }
        
        public override void OnEnter()
        {
            base.OnEnter();
            currentCount = 0;
        }
        
        public override NodeStatus Evaluate()
        {
            if (child == null)
            {
                return NodeStatus.Failure;
            }
            
            // 检查是否达到重复次数
            if (!infinite && currentCount >= repeatCount)
            {
                return NodeStatus.Success;
            }
            
            NodeStatus status = child.Evaluate();
            
            if (status != NodeStatus.Running)
            {
                currentCount++;
                
                if (infinite)
                {
                    // 无限重复,重置子节点并继续
                    child.OnReset();
                    behaviorTree.SetRunningNode(this);
                    return NodeStatus.Running;
                }
                else if (currentCount < repeatCount)
                {
                    // 还有剩余次数,重置子节点并继续
                    child.OnReset();
                    behaviorTree.SetRunningNode(this);
                    return NodeStatus.Running;
                }
                else
                {
                    // 达到指定次数
                    return NodeStatus.Success;
                }
            }
            else
            {
                // 子节点还在执行中
                behaviorTree.SetRunningNode(this);
                return NodeStatus.Running;
            }
        }
        
        public override void OnReset()
        {
            base.OnReset();
            currentCount = 0;
        }
    }
    
    /// <summary>
    /// 直到成功节点 - 重复执行直到子节点成功
    /// </summary>
    public class UntilSuccessNode : DecoratorNode
    {
        public UntilSuccessNode(string name, BTNode child = null) : base(name, child) { }
        
        public override NodeStatus Evaluate()
        {
            if (child == null)
            {
                return NodeStatus.Failure;
            }
            
            NodeStatus status = child.Evaluate();
            
            if (status == NodeStatus.Success)
            {
                return NodeStatus.Success;
            }
            else if (status == NodeStatus.Failure)
            {
                // 失败则重置并重试
                child.OnReset();
                behaviorTree.SetRunningNode(this);
                return NodeStatus.Running;
            }
            else
            {
                // 执行中
                behaviorTree.SetRunningNode(this);
                return NodeStatus.Running;
            }
        }
    }
    
    /// <summary>
    /// 条件装饰节点 - 只有条件满足时才执行子节点
    /// </summary>
    public class ConditionalDecoratorNode : DecoratorNode
    {
        private Func<bool> condition;
        private bool checkOnTick;
        
        public ConditionalDecoratorNode(string name, Func<bool> condition, 
                                       BTNode child = null, bool checkOnTick = true) 
            : base(name, child)
        {
            this.condition = condition;
            this.checkOnTick = checkOnTick;
        }
        
        public override NodeStatus Evaluate()
        {
            if (child == null)
            {
                return NodeStatus.Failure;
            }
            
            bool conditionMet = condition != null ? condition() : false;
            
            if (!conditionMet)
            {
                // 条件不满足,直接返回失败
                return NodeStatus.Failure;
            }
            
            NodeStatus status = child.Evaluate();
            
            if (checkOnTick && status == NodeStatus.Running)
            {
                // 在每次tick时检查条件
                conditionMet = condition != null ? condition() : false;
                if (!conditionMet)
                {
                    // 条件不再满足,中止子节点
                    child.OnAbort();
                    return NodeStatus.Failure;
                }
            }
            
            return status;
        }
    }
    
    /// <summary>
    /// 超时节点 - 限制子节点的执行时间
    /// </summary>
    public class TimeoutNode : DecoratorNode
    {
        private float timeoutDuration;
        private float startTime;
        private bool isTimedOut;
        
        public TimeoutNode(string name, float timeoutDuration, BTNode child = null) 
            : base(name, child)
        {
            this.timeoutDuration = timeoutDuration;
            isTimedOut = false;
        }
        
        public override void OnEnter()
        {
            base.OnEnter();
            startTime = Time.time;
            isTimedOut = false;
        }
        
        public override NodeStatus Evaluate()
        {
            if (child == null || isTimedOut)
            {
                return NodeStatus.Failure;
            }
            
            // 检查超时
            if (Time.time - startTime > timeoutDuration)
            {
                isTimedOut = true;
                child.OnAbort();
                return NodeStatus.Failure;
            }
            
            NodeStatus status = child.Evaluate();
            
            if (status != NodeStatus.Running)
            {
                // 子节点执行完成(成功或失败)
                return status;
            }
            else
            {
                // 子节点仍在执行中
                behaviorTree.SetRunningNode(this);
                return NodeStatus.Running;
            }
        }
        
        public override void OnReset()
        {
            base.OnReset();
            isTimedOut = false;
        }
    }
    
    /// <summary>
    /// 强制成功节点 - 无论子节点结果如何,都返回成功
    /// </summary>
    public class ForceSuccessNode : DecoratorNode
    {
        public ForceSuccessNode(string name, BTNode child = null) : base(name, child) { }
        
        public override NodeStatus Evaluate()
        {
            if (child == null)
            {
                return NodeStatus.Success;
            }
            
            NodeStatus status = child.Evaluate();
            
            if (status == NodeStatus.Running)
            {
                return NodeStatus.Running;
            }
            else
            {
                return NodeStatus.Success;
            }
        }
    }
    
    /// <summary>
    /// 强制失败节点 - 无论子节点结果如何,都返回失败
    /// </summary>
    public class ForceFailureNode : DecoratorNode
    {
        public ForceFailureNode(string name, BTNode child = null) : base(name, child) { }
        
        public override NodeStatus Evaluate()
        {
            if (child == null)
            {
                return NodeStatus.Failure;
            }
            
            NodeStatus status = child.Evaluate();
            
            if (status == NodeStatus.Running)
            {
                return NodeStatus.Running;
            }
            else
            {
                return NodeStatus.Failure;
            }
        }
    }
}

7.1.4 子树的复用与模块化设计

子树复用是行为树的重要特性,允许将复杂的行为模式封装为可重用的子树。这大大提高了行为树的可维护性和可扩展性。

namespace BehaviorTreeSystem
{
    /// <summary>
    /// 子树节点 - 引用另一个行为树
    /// </summary>
    public class SubtreeNode : BTNode
    {
        private BehaviorTree subtree;
        private string subtreeAssetPath; // 用于从资源加载
        
        public SubtreeNode(string name, BehaviorTree subtree = null) : base(name)
        {
            this.subtree = subtree;
        }
        
        public SubtreeNode(string name, string subtreeAssetPath) : base(name)
        {
            this.subtreeAssetPath = subtreeAssetPath;
        }
        
        public override void Initialize(BehaviorTree tree, Blackboard bb)
        {
            base.Initialize(tree, bb);
            
            if (subtree == null && !string.IsNullOrEmpty(subtreeAssetPath))
            {
                // 从资源加载子树
                LoadSubtreeFromAsset();
            }
            
            if (subtree != null)
            {
                // 共享黑板或创建子黑板
                Blackboard subtreeBlackboard = bb; // 共享同一个黑板
                // 或者: Blackboard subtreeBlackboard = new Blackboard();
                
                subtree.Initialize(tree.Owner, subtree.GetRootNode(), subtreeBlackboard);
            }
        }
        
        private void LoadSubtreeFromAsset()
        {
            // 在实际项目中,这里会从AssetBundle或Resources加载行为树资产
            // 这里简化实现
            Debug.Log($"加载子树资产: {subtreeAssetPath}");
        }
        
        public void SetSubtree(BehaviorTree newSubtree)
        {
            subtree = newSubtree;
            
            if (subtree != null && behaviorTree != null)
            {
                subtree.Initialize(behaviorTree.Owner, subtree.GetRootNode(), blackboard);
            }
        }
        
        public BehaviorTree GetSubtree()
        {
            return subtree;
        }
        
        public override NodeStatus Evaluate()
        {
            if (subtree == null)
            {
                return NodeStatus.Failure;
            }
            
            // 执行子树
            subtree.Update();
            
            // 判断子树状态
            // 这里简化处理,实际可能需要更复杂的逻辑来判断子树状态
            if (subtree.IsRunning)
            {
                behaviorTree.SetRunningNode(this);
                return NodeStatus.Running;
            }
            else
            {
                // 子树执行完成
                // 在实际实现中,可能需要获取子树的具体执行结果
                return NodeStatus.Success;
            }
        }
        
        public override void OnReset()
        {
            if (subtree != null)
            {
                subtree.Stop();
                subtree.Start();
            }
        }
        
        public override void OnAbort()
        {
            if (subtree != null)
            {
                subtree.Stop();
            }
        }
        
        // 扩展方法:获取子树根节点(用于调试和可视化)
        public BTNode GetSubtreeRoot()
        {
            return subtree?.GetRootNode();
        }
    }
    
    /// <summary>
    /// 行为树管理器 - 管理多个行为树和子树
    /// </summary>
    public class BehaviorTreeManager : MonoBehaviour
    {
        private static BehaviorTreeManager instance;
        
        private Dictionary<string, BehaviorTree> registeredTrees;
        private Dictionary<string, BTNode> registeredSubtrees;
        private Dictionary<GameObject, List<BehaviorTree>> activeTrees;
        
        public static BehaviorTreeManager Instance
        {
            get
            {
                if (instance == null)
                {
                    GameObject go = new GameObject("BehaviorTreeManager");
                    instance = go.AddComponent<BehaviorTreeManager>();
                    DontDestroyOnLoad(go);
                }
                return instance;
            }
        }
        
        private void Awake()
        {
            if (instance != null && instance != this)
            {
                Destroy(gameObject);
                return;
            }
            
            instance = this;
            Initialize();
        }
        
        private void Initialize()
        {
            registeredTrees = new Dictionary<string, BehaviorTree>();
            registeredSubtrees = new Dictionary<string, BTNode>();
            activeTrees = new Dictionary<GameObject, List<BehaviorTree>>();
        }
        
        private void Update()
        {
            // 更新所有活动行为树
            foreach (var kvp in activeTrees)
            {
                foreach (BehaviorTree tree in kvp.Value)
                {
                    if (tree.IsRunning)
                    {
                        tree.Update();
                    }
                }
            }
        }
        
        public void RegisterTree(string treeId, BehaviorTree tree)
        {
            if (!registeredTrees.ContainsKey(treeId))
            {
                registeredTrees[treeId] = tree;
                Debug.Log($"注册行为树: {treeId}");
            }
            else
            {
                Debug.LogWarning($"行为树已存在: {treeId}");
            }
        }
        
        public void UnregisterTree(string treeId)
        {
            if (registeredTrees.ContainsKey(treeId))
            {
                registeredTrees.Remove(treeId);
                Debug.Log($"注销行为树: {treeId}");
            }
        }
        
        public BehaviorTree GetTree(string treeId)
        {
            return registeredTrees.ContainsKey(treeId) ? registeredTrees[treeId] : null;
        }
        
        public void RegisterSubtree(string subtreeId, BTNode subtreeRoot)
        {
            if (!registeredSubtrees.ContainsKey(subtreeId))
            {
                registeredSubtrees[subtreeId] = subtreeRoot;
                Debug.Log($"注册子树: {subtreeId}");
            }
            else
            {
                Debug.LogWarning($"子树已存在: {subtreeId}");
            }
        }
        
        public BTNode GetSubtree(string subtreeId)
        {
            return registeredSubtrees.ContainsKey(subtreeId) ? registeredSubtrees[subtreeId] : null;
        }
        
        public void ActivateTree(GameObject owner, BehaviorTree tree)
        {
            if (!activeTrees.ContainsKey(owner))
            {
                activeTrees[owner] = new List<BehaviorTree>();
            }
            
            if (!activeTrees[owner].Contains(tree))
            {
                activeTrees[owner].Add(tree);
                tree.Start();
                Debug.Log($"激活行为树: {owner.name} -> {tree.GetRootNode()?.NodeName}");
            }
        }
        
        public void DeactivateTree(GameObject owner, BehaviorTree tree)
        {
            if (activeTrees.ContainsKey(owner) && activeTrees[owner].Contains(tree))
            {
                tree.Stop();
                activeTrees[owner].Remove(tree);
                Debug.Log($"停用行为树: {owner.name} -> {tree.GetRootNode()?.NodeName}");
                
                if (activeTrees[owner].Count == 0)
                {
                    activeTrees.Remove(owner);
                }
            }
        }
        
        public void DeactivateAllTrees(GameObject owner)
        {
            if (activeTrees.ContainsKey(owner))
            {
                foreach (BehaviorTree tree in activeTrees[owner])
                {
                    tree.Stop();
                }
                
                activeTrees.Remove(owner);
                Debug.Log($"停用所有行为树: {owner.name}");
            }
        }
        
        public List<BehaviorTree> GetActiveTrees(GameObject owner)
        {
            return activeTrees.ContainsKey(owner) ? 
                new List<BehaviorTree>(activeTrees[owner]) : 
                new List<BehaviorTree>();
        }
        
        public Dictionary<string, BehaviorTree> GetAllRegisteredTrees()
        {
            return new Dictionary<string, BehaviorTree>(registeredTrees);
        }
        
        public Dictionary<string, BTNode> GetAllRegisteredSubtrees()
        {
            return new Dictionary<string, BTNode>(registeredSubtrees);
        }
        
        // 保存行为树到文件(序列化)
        public void SaveTreeToFile(string treeId, string filePath)
        {
            // 在实际项目中,这里会实现序列化逻辑
            Debug.Log($"保存行为树到文件: {treeId} -> {filePath}");
        }
        
        // 从文件加载行为树
        public BehaviorTree LoadTreeFromFile(string filePath)
        {
            // 在实际项目中,这里会实现反序列化逻辑
            Debug.Log($"从文件加载行为树: {filePath}");
            return null;
        }
        
        // 导出子树为预制资源
        public void ExportSubtreeAsAsset(string subtreeId, string assetPath)
        {
            if (registeredSubtrees.ContainsKey(subtreeId))
            {
                // 在实际项目中,这里会实现资源导出逻辑
                Debug.Log($"导出子树为资源: {subtreeId} -> {assetPath}");
            }
        }
        
        private void OnDestroy()
        {
            // 清理所有活动行为树
            foreach (var kvp in activeTrees)
            {
                foreach (BehaviorTree tree in kvp.Value)
                {
                    tree.Stop();
                }
            }
            
            activeTrees.Clear();
            registeredTrees.Clear();
            registeredSubtrees.Clear();
        }
    }
}

7.1.5 行为树与有限状态机的对比分析

行为树和有限状态机都是游戏AI中常用的决策系统,各有优缺点。理解它们的差异对于选择合适的技术方案至关重要。

namespace BehaviorTreeSystem
{
    /// <summary>
    /// 行为树与有限状态机对比分析器
    /// </summary>
    public class FSMvsBTComparator : MonoBehaviour
    {
        [System.Serializable]
        public class ComparisonCriteria
        {
            public string criteriaName;
            public string fsmDescription;
            public string btDescription;
            public float fsmScore; // 0-10分
            public float btScore;  // 0-10分
            public string recommendation;
        }
        
        [Header("对比标准")]
        [SerializeField]
        private List<ComparisonCriteria> comparisonCriteria = new List<ComparisonCriteria>();
        
        [Header("案例分析")]
        [SerializeField]
        private string caseStudyName;
        
        [SerializeField]
        [TextArea(5, 10)]
        private string caseDescription;
        
        [SerializeField]
        private GameObject fsmImplementation;
        
        [SerializeField]
        private GameObject btImplementation;
        
        private void Awake()
        {
            InitializeComparisonCriteria();
        }
        
        private void InitializeComparisonCriteria()
        {
            comparisonCriteria.Clear();
            
            // 1. 复杂度管理
            comparisonCriteria.Add(new ComparisonCriteria
            {
                criteriaName = "复杂度管理",
                fsmDescription = "状态数量增多时,状态转换逻辑变得复杂,难以维护",
                btDescription = "树状结构自然表达层次关系,易于管理复杂行为",
                fsmScore = 6f,
                btScore = 9f,
                recommendation = "复杂行为系统推荐使用行为树"
            });
            
            // 2. 可扩展性
            comparisonCriteria.Add(new ComparisonCriteria
            {
                criteriaName = "可扩展性",
                fsmDescription = "添加新状态需要修改多个转换条件,容易引入错误",
                btDescription = "可以轻松添加新节点或子树,不影响现有逻辑",
                fsmScore = 5f,
                btScore = 9f,
                recommendation = "需要频繁扩展的系统推荐行为树"
            });
            
            // 3. 可读性
            comparisonCriteria.Add(new ComparisonCriteria
            {
                criteriaName = "可读性",
                fsmDescription = "状态图直观,但状态转换逻辑分散在代码中",
                btDescription = "树状结构清晰展示行为层次,易于理解和调试",
                fsmScore = 7f,
                btScore = 9f,
                recommendation = "团队协作项目推荐行为树"
            });
            
            // 4. 执行效率
            comparisonCriteria.Add(new ComparisonCriteria
            {
                criteriaName = "执行效率",
                fsmDescription = "状态切换开销小,适合实时性要求高的场景",
                btDescription = "节点遍历需要时间,但优化后效率可接受",
                fsmScore = 9f,
                btScore = 7f,
                recommendation = "对性能要求极高的场景推荐有限状态机"
            });
            
            // 5. 并行处理
            comparisonCriteria.Add(new ComparisonCriteria
            {
                criteriaName = "并行处理",
                fsmDescription = "传统FSM难以处理并行状态,需要特殊设计",
                btDescription = "原生支持并行节点,易于实现并发行为",
                fsmScore = 4f,
                btScore = 9f,
                recommendation = "需要并发行为的系统推荐行为树"
            });
            
            // 6. 条件检查
            comparisonCriteria.Add(new ComparisonCriteria
            {
                criteriaName = "条件检查",
                fsmDescription = "条件检查集中在状态转换逻辑中",
                btDescription = "条件可以作为独立节点,实现关注点分离",
                fsmScore = 6f,
                btScore = 8f,
                recommendation = "条件逻辑复杂的系统推荐行为树"
            });
            
            // 7. 复用性
            comparisonCriteria.Add(new ComparisonCriteria
            {
                criteriaName = "复用性",
                fsmDescription = "状态逻辑难以复用,容易产生代码重复",
                btDescription = "子树机制支持高度复用,减少重复代码",
                fsmScore = 5f,
                btScore = 9f,
                recommendation = "需要大量复用行为的系统推荐行为树"
            });
            
            // 8. 调试支持
            comparisonCriteria.Add(new ComparisonCriteria
            {
                criteriaName = "调试支持",
                fsmDescription = "当前状态明确,但转换历史难以追踪",
                btDescription = "可以记录完整执行路径,便于问题定位",
                fsmScore = 6f,
                btScore = 8f,
                recommendation = "调试需求高的项目推荐行为树"
            });
            
            // 9. 学习曲线
            comparisonCriteria.Add(new ComparisonCriteria
            {
                criteriaName = "学习曲线",
                fsmDescription = "概念简单,易于初学者理解和实现",
                btDescription = "概念较多,需要时间掌握各种节点类型",
                fsmScore = 9f,
                btScore = 6f,
                recommendation = "新手团队或简单AI推荐有限状态机"
            });
            
            // 10. 适用场景
            comparisonCriteria.Add(new ComparisonCriteria
            {
                criteriaName = "适用场景",
                fsmDescription = "适合状态明确、转换简单的AI(如门、开关、简单敌人)",
                btDescription = "适合复杂、层次化的AI(如NPC、BOSS、策略单位)",
                fsmScore = 7f,
                btScore = 8f,
                recommendation = "根据AI复杂度选择合适技术"
            });
        }
        
        public void AnalyzeAndCompare()
        {
            Debug.Log("=== 行为树 vs 有限状态机 对比分析 ===");
            Debug.Log($"案例分析: {caseStudyName}");
            Debug.Log($"案例描述: {caseDescription}");
            
            float totalFsmScore = 0f;
            float totalBtScore = 0f;
            int criteriaCount = comparisonCriteria.Count;
            
            foreach (ComparisonCriteria criteria in comparisonCriteria)
            {
                Debug.Log($"\n[{criteria.criteriaName}]");
                Debug.Log($"FSM: {criteria.fsmDescription} (评分: {criteria.fsmScore})");
                Debug.Log($"BT: {criteria.btDescription} (评分: {criteria.btScore})");
                Debug.Log($"推荐: {criteria.recommendation}");
                
                totalFsmScore += criteria.fsmScore;
                totalBtScore += criteria.btScore;
            }
            
            float avgFsmScore = totalFsmScore / criteriaCount;
            float avgBtScore = totalBtScore / criteriaCount;
            
            Debug.Log($"\n=== 总结 ===");
            Debug.Log($"FSM平均评分: {avgFsmScore:F1}/10");
            Debug.Log($"BT平均评分: {avgBtScore:F1}/10");
            
            if (avgBtScore > avgFsmScore + 1f)
            {
                Debug.Log("推荐使用: 行为树 (Behavior Tree)");
                Debug.Log("理由: 行为树在复杂度管理、可扩展性、可读性和并行处理方面优势明显");
            }
            else if (avgFsmScore > avgBtScore + 1f)
            {
                Debug.Log("推荐使用: 有限状态机 (Finite State Machine)");
                Debug.Log("理由: 有限状态机在执行效率和学习曲线方面更有优势,适合简单AI");
            }
            else
            {
                Debug.Log("推荐: 根据具体需求选择");
                Debug.Log("理由: 两种技术各有优势,可以考虑混合使用或根据团队经验选择");
            }
            
            // 显示具体实现
            ShowImplementations();
        }
        
        private void ShowImplementations()
        {
            if (fsmImplementation != null)
            {
                Debug.Log($"\n有限状态机实现示例: {fsmImplementation.name}");
                // 这里可以展示FSM的具体实现代码
            }
            
            if (btImplementation != null)
            {
                Debug.Log($"\n行为树实现示例: {btImplementation.name}");
                // 这里可以展示BT的具体实现代码
            }
        }
        
        public void RunCaseStudy()
        {
            Debug.Log($"运行案例研究: {caseStudyName}");
            
            // 在实际项目中,这里会运行两种实现的对比测试
            // 测量性能、内存使用、代码复杂度等指标
            
            RunFSMTest();
            RunBTTest();
            CompareResults();
        }
        
        private void RunFSMTest()
        {
            Debug.Log("运行有限状态机测试...");
            
            if (fsmImplementation != null)
            {
                // 激活FSM组件并测试
                MonoBehaviour[] fsmComponents = fsmImplementation.GetComponents<MonoBehaviour>();
                foreach (MonoBehaviour component in fsmComponents)
                {
                    if (component.GetType().Name.Contains("FSM") || 
                        component.GetType().Name.Contains("State"))
                    {
                        Debug.Log($"找到FSM组件: {component.GetType().Name}");
                        // 运行测试逻辑
                    }
                }
            }
        }
        
        private void RunBTTest()
        {
            Debug.Log("运行行为树测试...");
            
            if (btImplementation != null)
            {
                // 激活行为树组件并测试
                BehaviorTreeController btController = btImplementation.GetComponent<BehaviorTreeController>();
                if (btController != null)
                {
                    Debug.Log($"找到行为树控制器: {btController.name}");
                    // 运行测试逻辑
                }
            }
        }
        
        private void CompareResults()
        {
            Debug.Log("对比测试结果...");
            
            // 在实际项目中,这里会比较两种实现的性能数据
            // 包括帧率、内存占用、CPU时间等
            
            Debug.Log("测试完成,详细报告已生成");
        }
        
        public List<ComparisonCriteria> GetComparisonResults()
        {
            return new List<ComparisonCriteria>(comparisonCriteria);
        }
        
        public void ExportReport(string filePath)
        {
            // 生成并导出对比报告
            string report = GenerateComparisonReport();
            System.IO.File.WriteAllText(filePath, report);
            Debug.Log($"报告已导出到: {filePath}");
        }
        
        private string GenerateComparisonReport()
        {
            System.Text.StringBuilder sb = new System.Text.StringBuilder();
            
            sb.AppendLine("行为树 vs 有限状态机 对比分析报告");
            sb.AppendLine($"生成时间: {System.DateTime.Now}");
            sb.AppendLine($"案例名称: {caseStudyName}");
            sb.AppendLine($"案例描述: {caseDescription}");
            sb.AppendLine();
            sb.AppendLine("=== 详细对比 ===");
            
            foreach (ComparisonCriteria criteria in comparisonCriteria)
            {
                sb.AppendLine($"\n[{criteria.criteriaName}]");
                sb.AppendLine($"FSM: {criteria.fsmDescription}");
                sb.AppendLine($"评分: {criteria.fsmScore}/10");
                sb.AppendLine($"BT: {criteria.btDescription}");
                sb.AppendLine($"评分: {criteria.btScore}/10");
                sb.AppendLine($"推荐: {criteria.recommendation}");
            }
            
            // 计算总分
            float totalFsmScore = 0f;
            float totalBtScore = 0f;
            foreach (ComparisonCriteria criteria in comparisonCriteria)
            {
                totalFsmScore += criteria.fsmScore;
                totalBtScore += criteria.btScore;
            }
            
            sb.AppendLine("\n=== 总结 ===");
            sb.AppendLine($"FSM总分: {totalFsmScore}/{(comparisonCriteria.Count * 10)}");
            sb.AppendLine($"BT总分: {totalBtScore}/{(comparisonCriteria.Count * 10)}");
            
            if (totalBtScore > totalFsmScore)
            {
                sb.AppendLine("总体推荐: 行为树 (Behavior Tree)");
            }
            else if (totalFsmScore > totalBtScore)
            {
                sb.AppendLine("总体推荐: 有限状态机 (Finite State Machine)");
            }
            else
            {
                sb.AppendLine("总体推荐: 根据具体需求选择");
            }
            
            return sb.ToString();
        }
    }
    
    /// <summary>
    /// 混合系统 - 结合FSM和BT的优势
    /// </summary>
    public class HybridAISystem : MonoBehaviour
    {
        [System.Serializable]
        public class FSMState
        {
            public string stateName;
            public BehaviorTree behaviorTree;
            public List<Transition> transitions;
            
            [System.Serializable]
            public class Transition
            {
                public string targetState;
                public ConditionNode condition;
            }
        }
        
        [Header("混合系统配置")]
        [SerializeField]
        private List<FSMState> states = new List<FSMState>();
        
        [SerializeField]
        private string initialState;
        
        [Header("当前状态")]
        [SerializeField]
        private string currentState;
        
        [SerializeField]
        private FSMState currentStateData;
        
        private Blackboard sharedBlackboard;
        private bool isActive;
        
        private void Awake()
        {
            InitializeHybridSystem();
        }
        
        private void InitializeHybridSystem()
        {
            sharedBlackboard = new Blackboard();
            isActive = true;
            
            // 初始化所有状态的行为树
            foreach (FSMState state in states)
            {
                if (state.behaviorTree != null)
                {
                    state.behaviorTree.Initialize(gameObject, state.behaviorTree.GetRootNode(), sharedBlackboard);
                }
            }
            
            // 设置初始状态
            if (!string.IsNullOrEmpty(initialState))
            {
                ChangeState(initialState);
            }
            else if (states.Count > 0)
            {
                ChangeState(states[0].stateName);
            }
            
            Debug.Log("混合AI系统初始化完成");
        }
        
        private void Update()
        {
            if (!isActive || currentStateData == null)
            {
                return;
            }
            
            // 执行当前状态的行为树
            if (currentStateData.behaviorTree != null)
            {
                currentStateData.behaviorTree.Update();
            }
            
            // 检查状态转换
            CheckStateTransitions();
        }
        
        private void CheckStateTransitions()
        {
            if (currentStateData == null || currentStateData.transitions == null)
            {
                return;
            }
            
            foreach (FSMState.Transition transition in currentStateData.transitions)
            {
                if (transition.condition != null)
                {
                    // 初始化条件节点(如果尚未初始化)
                    if (transition.condition.behaviorTree == null)
                    {
                        BehaviorTree tempTree = new BehaviorTree(gameObject, transition.condition, sharedBlackboard);
                        transition.condition.Initialize(tempTree, sharedBlackboard);
                    }
                    
                    // 检查条件
                    NodeStatus conditionStatus = transition.condition.Evaluate();
                    
                    if (conditionStatus == NodeStatus.Success)
                    {
                        ChangeState(transition.targetState);
                        break;
                    }
                }
            }
        }
        
        private void ChangeState(string newStateName)
        {
            if (currentState == newStateName)
            {
                return;
            }
            
            // 退出当前状态
            if (currentStateData != null && currentStateData.behaviorTree != null)
            {
                currentStateData.behaviorTree.Stop();
            }
            
            // 查找新状态
            FSMState newState = states.Find(s => s.stateName == newStateName);
            if (newState == null)
            {
                Debug.LogError($"状态不存在: {newStateName}");
                return;
            }
            
            // 进入新状态
            currentState = newStateName;
            currentStateData = newState;
            
            if (currentStateData.behaviorTree != null)
            {
                currentStateData.behaviorTree.Start();
            }
            
            Debug.Log($"混合系统状态转换: {currentState} -> {newStateName}");
        }
        
        public void SetActive(bool active)
        {
            isActive = active;
            
            if (isActive && currentStateData != null && currentStateData.behaviorTree != null)
            {
                currentStateData.behaviorTree.Start();
            }
            else if (!isActive && currentStateData != null && currentStateData.behaviorTree != null)
            {
                currentStateData.behaviorTree.Stop();
            }
        }
        
        public void AddState(string stateName, BehaviorTree behaviorTree)
        {
            FSMState newState = new FSMState
            {
                stateName = stateName,
                behaviorTree = behaviorTree,
                transitions = new List<FSMState.Transition>()
            };
            
            states.Add(newState);
            
            if (string.IsNullOrEmpty(initialState))
            {
                initialState = stateName;
                ChangeState(stateName);
            }
        }
        
        public void AddTransition(string fromState, string toState, ConditionNode condition)
        {
            FSMState state = states.Find(s => s.stateName == fromState);
            if (state != null)
            {
                state.transitions.Add(new FSMState.Transition
                {
                    targetState = toState,
                    condition = condition
                });
            }
        }
        
        public string CurrentState
        {
            get { return currentState; }
        }
        
        public Blackboard SharedBlackboard
        {
            get { return sharedBlackboard; }
        }
        
        private void OnDrawGizmosSelected()
        {
            if (!Application.isPlaying)
            {
                return;
            }
            
            // 绘制当前状态信息
            #if UNITY_EDITOR
            string info = $"混合AI系统\n";
            info += $"当前状态: {currentState}\n";
            info += $"状态数量: {states.Count}";
            
            UnityEditor.Handles.Label(
                transform.position + Vector3.up * 2.5f,
                info
            );
            #endif
        }
    }
}

7.1.6 行为树的协同执行机制

协同程序(Coroutine)是Unity中实现异步操作的重要机制,在行为树中可以用来处理需要时间的动作,如移动、等待、动画播放等。

namespace BehaviorTreeSystem
{
    /// <summary>
    /// 协同动作节点基类 - 支持协同程序的动作
    /// </summary>
    public abstract class CoroutineActionNode : ActionNode
    {
        protected Coroutine executionCoroutine;
        protected MonoBehaviour coroutineOwner;
        
        public CoroutineActionNode(string name) : base(name)
        {
        }
        
        public override void Initialize(BehaviorTree tree, Blackboard bb)
        {
            base.Initialize(tree, bb);
            
            // 获取协同程序的所有者
            coroutineOwner = tree.Owner.GetComponent<MonoBehaviour>();
            if (coroutineOwner == null)
            {
                coroutineOwner = tree.Owner.AddComponent<EmptyMonoBehaviour>();
            }
        }
        
        public override void OnEnter()
        {
            base.OnEnter();
            
            // 启动协同程序
            if (coroutineOwner != null)
            {
                executionCoroutine = coroutineOwner.StartCoroutine(ExecuteCoroutine());
            }
        }
        
        public override void OnExit()
        {
            base.OnExit();
            
            // 停止协同程序
            if (executionCoroutine != null && coroutineOwner != null)
            {
                coroutineOwner.StopCoroutine(executionCoroutine);
                executionCoroutine = null;
            }
        }
        
        public override void OnAbort()
        {
            base.OnAbort();
            
            // 中止时也停止协同程序
            if (executionCoroutine != null && coroutineOwner != null)
            {
                coroutineOwner.StopCoroutine(executionCoroutine);
                executionCoroutine = null;
            }
        }
        
        public override NodeStatus Execute()
        {
            // 协同程序模式下,Execute方法只返回当前状态
            return isRunning ? NodeStatus.Running : NodeStatus.Success;
        }
        
        protected abstract IEnumerator ExecuteCoroutine();
        
        // 完成协同程序的回调
        protected void OnCoroutineCompleted(NodeStatus status)
        {
            if (isRunning)
            {
                // 设置最终状态并退出
                isRunning = false;
                
                // 通知行为树
                behaviorTree.RecordNodeExecution(this, status);
                OnExit();
            }
        }
    }
    
    /// <summary>
    /// 空MonoBehaviour类,用于没有MonoBehaviour的GameObject
    /// </summary>
    public class EmptyMonoBehaviour : MonoBehaviour
    {
        // 空类,仅用于承载协同程序
    }
    
    /// <summary>
    /// 等待节点 - 等待指定时间
    /// </summary>
    public class WaitNode : CoroutineActionNode
    {
        private float waitDuration;
        private float randomVariance;
        
        public WaitNode(string name, float duration, float variance = 0f) : base(name)
        {
            waitDuration = duration;
            randomVariance = variance;
        }
        
        protected override IEnumerator ExecuteCoroutine()
        {
            // 计算实际等待时间
            float actualWaitTime = waitDuration;
            if (randomVariance > 0f)
            {
                actualWaitTime += UnityEngine.Random.Range(-randomVariance, randomVariance);
                actualWaitTime = Mathf.Max(0f, actualWaitTime);
            }
            
            Debug.Log($"{nodeName}: 等待 {actualWaitTime:F2} 秒");
            
            yield return new WaitForSeconds(actualWaitTime);
            
            OnCoroutineCompleted(NodeStatus.Success);
        }
    }
    
    /// <summary>
    /// 移动到位置节点
    /// </summary>
    public class MoveToPositionNode : CoroutineActionNode
    {
        private Vector3 targetPosition;
        private float moveSpeed;
        private float stoppingDistance;
        private string positionKey; // 黑板中位置数据的键名
        
        public MoveToPositionNode(string name, Vector3 position, float speed = 3f, 
                                 float stopDistance = 0.5f) : base(name)
        {
            targetPosition = position;
            moveSpeed = speed;
            stoppingDistance = stopDistance;
        }
        
        public MoveToPositionNode(string name, string positionKey, float speed = 3f,
                                 float stopDistance = 0.5f) : base(name)
        {
            this.positionKey = positionKey;
            moveSpeed = speed;
            stoppingDistance = stopDistance;
        }
        
        protected override IEnumerator ExecuteCoroutine()
        {
            // 获取目标位置
            Vector3 finalTarget = targetPosition;
            
            if (!string.IsNullOrEmpty(positionKey) && blackboard.HasValue(positionKey))
            {
                finalTarget = blackboard.GetValue<Vector3>(positionKey);
            }
            
            Transform transform = behaviorTree.Owner.transform;
            
            Debug.Log($"{nodeName}: 移动到位置 {finalTarget}");
            
            // 移动循环
            while (true)
            {
                Vector3 direction = (finalTarget - transform.position).normalized;
                float distance = Vector3.Distance(transform.position, finalTarget);
                
                if (distance <= stoppingDistance)
                {
                    // 到达目标
                    OnCoroutineCompleted(NodeStatus.Success);
                    yield break;
                }
                
                // 移动
                transform.position += direction * moveSpeed * Time.deltaTime;
                
                // 面向移动方向
                if (direction.magnitude > 0.1f)
                {
                    Quaternion targetRotation = Quaternion.LookRotation(direction);
                    transform.rotation = Quaternion.Slerp(
                        transform.rotation, 
                        targetRotation, 
                        5f * Time.deltaTime
                    );
                }
                
                yield return null;
            }
        }
    }
    
    /// <summary>
    /// 播放动画节点
    /// </summary>
    public class PlayAnimationNode : CoroutineActionNode
    {
        private string animationName;
        private float animationSpeed;
        private bool waitForCompletion;
        
        private Animator animator;
        
        public PlayAnimationNode(string name, string animationName, 
                               float speed = 1f, bool wait = true) : base(name)
        {
            this.animationName = animationName;
            animationSpeed = speed;
            waitForCompletion = wait;
        }
        
        public override void Initialize(BehaviorTree tree, Blackboard bb)
        {
            base.Initialize(tree, bb);
            
            // 获取Animator组件
            animator = behaviorTree.Owner.GetComponent<Animator>();
        }
        
        protected override IEnumerator ExecuteCoroutine()
        {
            if (animator == null)
            {
                Debug.LogError($"{nodeName}: 没有找到Animator组件");
                OnCoroutineCompleted(NodeStatus.Failure);
                yield break;
            }
            
            Debug.Log($"{nodeName}: 播放动画 {animationName}");
            
            // 设置动画参数
            animator.speed = animationSpeed;
            animator.Play(animationName);
            
            if (waitForCompletion)
            {
                // 等待动画播放完成
                yield return new WaitForSeconds(0.1f); // 等待动画开始
                
                while (animator.GetCurrentAnimatorStateInfo(0).normalizedTime < 1f)
                {
                    yield return null;
                }
                
                OnCoroutineCompleted(NodeStatus.Success);
            }
            else
            {
                // 不等待动画完成
                yield return null;
                OnCoroutineCompleted(NodeStatus.Success);
            }
        }
    }
    
    /// <summary>
    /// 等待条件节点 - 等待某个条件满足
    /// </summary>
    public class WaitUntilConditionNode : CoroutineActionNode
    {
        private Func<bool> condition;
        private float timeout;
        private float checkInterval;
        
        public WaitUntilConditionNode(string name, Func<bool> condition, 
                                     float timeout = -1f, float interval = 0.1f) : base(name)
        {
            this.condition = condition;
            this.timeout = timeout;
            checkInterval = interval;
        }
        
        protected override IEnumerator ExecuteCoroutine()
        {
            float startTime = Time.time;
            
            Debug.Log($"{nodeName}: 等待条件满足");
            
            while (true)
            {
                // 检查超时
                if (timeout > 0 && Time.time - startTime > timeout)
                {
                    Debug.Log($"{nodeName}: 等待超时");
                    OnCoroutineCompleted(NodeStatus.Failure);
                    yield break;
                }
                
                // 检查条件
                if (condition != null && condition())
                {
                    Debug.Log($"{nodeName}: 条件满足");
                    OnCoroutineCompleted(NodeStatus.Success);
                    yield break;
                }
                
                // 等待一段时间再检查
                yield return new WaitForSeconds(checkInterval);
            }
        }
    }
    
    /// <summary>
    /// 并行协同节点 - 同时执行多个协同动作
    /// </summary>
    public class ParallelCoroutineNode : CompositeNode
    {
        private List<Coroutine> coroutines;
        private MonoBehaviour coroutineOwner;
        private Dictionary<BTNode, NodeStatus> childResults;
        private bool allChildrenStarted;
        
        public ParallelCoroutineNode(string name) : base(name)
        {
            coroutines = new List<Coroutine>();
            childResults = new Dictionary<BTNode, NodeStatus>();
        }
        
        public override void Initialize(BehaviorTree tree, Blackboard bb)
        {
            base.Initialize(tree, bb);
            
            // 获取协同程序的所有者
            coroutineOwner = tree.Owner.GetComponent<MonoBehaviour>();
            if (coroutineOwner == null)
            {
                coroutineOwner = tree.Owner.AddComponent<EmptyMonoBehaviour>();
            }
        }
        
        public override void OnEnter()
        {
            base.OnEnter();
            
            childResults.Clear();
            allChildrenStarted = false;
            
            // 启动所有子节点的协同程序
            foreach (BTNode child in children)
            {
                if (child is CoroutineActionNode coroutineNode)
                {
                    // 启动协同程序
                    Coroutine coroutine = coroutineOwner.StartCoroutine(
                        ExecuteChildCoroutine(coroutineNode)
                    );
                    coroutines.Add(coroutine);
                    childResults[child] = NodeStatus.Running;
                }
            }
            
            allChildrenStarted = true;
        }
        
        private IEnumerator ExecuteChildCoroutine(CoroutineActionNode childNode)
        {
            // 手动调用子节点的OnEnter来启动协同程序
            childNode.OnEnter();
            
            // 等待子节点完成
            while (childNode.IsRunning)
            {
                yield return null;
            }
            
            // 获取结果(这里简化处理,实际需要从子节点获取状态)
            NodeStatus status = NodeStatus.Success; // 假设成功
            childResults[childNode] = status;
        }
        
        public override NodeStatus Evaluate()
        {
            if (!allChildrenStarted)
            {
                behaviorTree.SetRunningNode(this);
                return NodeStatus.Running;
            }
            
            // 检查所有子节点的状态
            int successCount = 0;
            int failureCount = 0;
            int runningCount = 0;
            
            foreach (BTNode child in children)
            {
                NodeStatus status;
                
                if (childResults.ContainsKey(child))
                {
                    status = childResults[child];
                }
                else
                {
                    status = NodeStatus.Running;
                }
                
                switch (status)
                {
                    case NodeStatus.Success:
                        successCount++;
                        break;
                    case NodeStatus.Failure:
                        failureCount++;
                        break;
                    case NodeStatus.Running:
                        runningCount++;
                        break;
                }
            }
            
            // 判断结果
            if (runningCount > 0)
            {
                behaviorTree.SetRunningNode(this);
                return NodeStatus.Running;
            }
            else if (failureCount > 0)
            {
                // 有子节点失败
                return NodeStatus.Failure;
            }
            else
            {
                // 所有子节点成功
                return NodeStatus.Success;
            }
        }
        
        public override void OnExit()
        {
            base.OnExit();
            
            // 停止所有协同程序
            foreach (Coroutine coroutine in coroutines)
            {
                if (coroutineOwner != null)
                {
                    coroutineOwner.StopCoroutine(coroutine);
                }
            }
            
            coroutines.Clear();
            childResults.Clear();
        }
        
        public override void OnAbort()
        {
            base.OnAbort();
            
            // 中止所有子节点
            foreach (BTNode child in children)
            {
                child.OnAbort();
            }
        }
    }
    
    /// <summary>
    /// 顺序协同节点 - 按顺序执行协同动作
    /// </summary>
    public class SequenceCoroutineNode : CompositeNode
    {
        private Coroutine sequenceCoroutine;
        private MonoBehaviour coroutineOwner;
        
        public SequenceCoroutineNode(string name) : base(name)
        {
        }
        
        public override void Initialize(BehaviorTree tree, Blackboard bb)
        {
            base.Initialize(tree, bb);
            
            // 获取协同程序的所有者
            coroutineOwner = tree.Owner.GetComponent<MonoBehaviour>();
            if (coroutineOwner == null)
            {
                coroutineOwner = tree.Owner.AddComponent<EmptyMonoBehaviour>();
            }
        }
        
        public override void OnEnter()
        {
            base.OnEnter();
            
            // 启动顺序执行协同程序
            if (coroutineOwner != null)
            {
                sequenceCoroutine = coroutineOwner.StartCoroutine(ExecuteSequence());
            }
        }
        
        private IEnumerator ExecuteSequence()
        {
            for (int i = 0; i < children.Count; i++)
            {
                BTNode child = children[i];
                
                if (child is CoroutineActionNode coroutineNode)
                {
                    // 执行子节点
                    coroutineNode.OnEnter();
                    
                    // 等待子节点完成
                    while (coroutineNode.IsRunning)
                    {
                        yield return null;
                    }
                    
                    // 检查子节点状态
                    // 这里简化处理,假设总是成功
                    // 实际需要处理失败情况并中断序列
                }
                else if (child is ActionNode actionNode)
                {
                    // 非协同动作节点,直接执行
                    NodeStatus status = actionNode.Evaluate();
                    
                    if (status == NodeStatus.Failure)
                    {
                        // 失败则中断序列
                        break;
                    }
                }
            }
            
            // 序列执行完成
            // 这里需要通知行为树节点完成
        }
        
        public override NodeStatus Evaluate()
        {
            // 协同程序模式下,Evaluate只返回当前状态
            // 实际状态由协同程序控制
            return NodeStatus.Running;
        }
        
        public override void OnExit()
        {
            base.OnExit();
            
            // 停止协同程序
            if (sequenceCoroutine != null && coroutineOwner != null)
            {
                coroutineOwner.StopCoroutine(sequenceCoroutine);
                sequenceCoroutine = null;
            }
        }
        
        public override void OnAbort()
        {
            base.OnAbort();
            
            // 中止所有子节点
            foreach (BTNode child in children)
            {
                child.OnAbort();
            }
        }
    }
}

通过以上完整的行为树系统实现,我们建立了一个功能齐全、模块化、可扩展的行为树框架。这个框架包含了行为树的所有核心组件:节点基类、各种类型的节点(动作、条件、组合、装饰)、黑板系统、子树复用、协同程序支持以及与有限状态机的对比和混合系统。

在接下来的章节中,我们将使用这个框架来构建具体的AI行为树实例,展示如何在商业游戏项目中应用行为树技术。

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐