AI决策算法 行为树实现(二)

顺序节点:SequenceNode

并行节点:ParallelNode ( 当一个节点不通过就不执行 )

并行节点2:ParallelFlexibleNode ( 当所有节点不通过才不执行 )

选择节点: PrioritySelectorNode



实现:


顺序节点:SequenceNode

namespace BehaviorTree
{
    public class SequenceNode : BaseNode
    {
        private BaseNode activeChild;     // 激活的节点
        private int activeIndex = -1;     // 激活节点的Index

        public SequenceNode(PreconditionNode precondition = null) : base(precondition) { }

        /// <summary>
        /// 检查第一个子节点是否通过
        /// </summary>
        /// <returns></returns>
        protected override bool DoEvaluate()
        {
            //返回第一个节点是否通过
           if(activeChild != null)
           {
               // 如果有激活节点又不通过条件,清空重置
               if(!activeChild.Evaluate)
               {
                   activeChild.Clear();
                   activeChild = null;
                   activeIndex = -1;
               }
               return activeChild.Evaluate;
           }
           else
           {
               return children[0].Evaluate;
           }
        }

        /// <summary>
        /// 顺序执行
        /// </summary>
        /// <returns></returns>
        public override NodeResult Tick()
        {
            if(activeChild == null)
            {
                activeChild = children[0];
                activeIndex = 0;
            }

            //当节点结束就执行下个节点
            NodeResult result = activeChild.Tick();
            if(result == NodeResult.Ended)
            {
                activeIndex++;
                if(activeIndex >= children.Count)
                {
                    activeChild.Clear();
                    activeChild = null;
                    activeIndex = -1;
                }
                else
                {
                    activeChild.Clear();
                    activeChild = children[activeIndex];
                    result = NodeResult.Running;
                }
            }
            return result;
        }

        /// <summary>
        /// 清除激活节点
        /// </summary>
        public override void Clear()
        {
            if(activeChild != null)
            {
                activeChild = null;
                activeIndex = -1;
            }

            foreach (var node in children)
                node.Clear();

        }

    }
}


并行节点:ParallelNode ( 当一个节点不通过就不执行 )

namespace BehaviorTree
{
    public class ParallelNode : BaseNode
    {
        protected List<NodeResult> results;     // 子节点结果记录表
        protected ParallelType type;            // 并行类型

        public ParallelNode(ParallelType type) : this(type, null) { }

        public ParallelNode(ParallelType type,PreconditionNode precondition) : base(precondition)
        {
            results = new List<NodeResult>();
            this.type = type;
        }

        /// <summary>
        /// 并行检查:一个不通过就不执行
        /// </summary>
        /// <returns></returns>
        protected override bool DoEvaluate()
        {
            foreach(var node in children)
            {
                //一个不通过就不通过
                if (!node.Evaluate)
                    return false;
            }
            return true;
        }

        /// <summary>
        /// 并行执行
        /// </summary>
        /// <returns></returns>
        public override NodeResult Tick()
        {
            int endingResultCount = 0;

            for(int i = 0;i < children.Count;i++)
            {
                if(type == ParallelType.And)              // 全部结束才返回
                {
                    if (results[i] == NodeResult.Running)
                        results[i] = children[i].Tick();
                    //Tick后再次检测
                    if (results[i] == NodeResult.Ended)
                        endingResultCount++;
                }
                else                                      // 出现一个结束就返回
                {
                    if (results[i] == NodeResult.Running)
                        results[i] = children[i].Tick();
                    //Tick后再次检测
                    if (results[i] == NodeResult.Ended)
                    {
                        ResetResults();
                        return NodeResult.Ended;
                    }
                }
            }

            //如果全部结束了
            if (endingResultCount == children.Count)
            {
                ResetResults();
                return NodeResult.Ended;
            }

            return NodeResult.Running;
        }

        public override void Clear()
        {
            foreach (var child in children)
                child.Clear();
        }

        public override void AddChild(BaseNode node)
        {
            base.AddChild(node);
            results.Add(NodeResult.Running);
        }

        public override void RemoveChild(BaseNode node)
        {
            int index = children.IndexOf(node);
            results.RemoveAt(index);
            base.RemoveChild(node);
        }

        /// <summary>
        /// 重置子节点结果表
        /// </summary>
        private void ResetResults()
        {
            for (int i = 0; i < results.Count; i++)
                results[i] = NodeResult.Running;
        }

    }

    //并行类型
    public enum ParallelType
    {
        And,
        Or
    }

}


并行节点2:ParallelFlexibleNode ( 当所有节点不通过才不执行 )

namespace BehaviorTree
{
    public class ParallelFlexibleNode : BaseNode
    {
        private List<bool> activeList = new List<bool>();

        public ParallelFlexibleNode(PreconditionNode precondition = null) : base(precondition) { }

        /// <summary>
        /// 并行检查:所有都不通过才不通过
        /// </summary>
        /// <returns></returns>
        protected override bool DoEvaluate()
        {
            int numActiveChildren = 0;

            for(int i = 0; i < children.Count;i++)
            {
                BaseNode child = children[i];
                if(child.Evaluate)
                {
                    activeList[i] = true;
                    numActiveChildren++;
                }
                else
                {
                    activeList[i] = false;
                }
            }

            if (numActiveChildren == 0)
                return false;

            return true;
        }

        /// <summary>
        /// 执行所有通过的节点
        /// </summary>
        /// <returns></returns>
        public override NodeResult Tick()
        {
            int numRunningChildren = 0;
            for(int i = 0; i < children.Count ;i++)
            {
                bool active = activeList[i];
                if(active)
                {
                    NodeResult result = children[i].Tick();
                    if (result == NodeResult.Running)
                        numRunningChildren++;
                }
            }

            if (numRunningChildren == 0)
                return NodeResult.Ended;

            return NodeResult.Running;
        }

        public override void AddChild(BaseNode node)
        {
            base.AddChild(node);
            activeList.Add(false);
        }

        public override void RemoveChild(BaseNode node)
        {
            int index = children.IndexOf(node);
            activeList.RemoveAt(index);
            base.RemoveChild(node);
        }

        public override void Clear()
        {
            base.Clear();
            foreach (var child in children)
                child.Clear();
        }


    }

}



选择节点: PrioritySelectorNode

namespace BehaviorTree
{
    public class PrioritySelectorNode : BaseNode
    {

        private BaseNode _activeChild; // 激活节点

        public PrioritySelectorNode(PreconditionNode precondition = null) : base(precondition) { }

        /// <summary>
        /// 选择检测:激活第一个通过的节点返回
        /// </summary>
        /// <returns></returns>
        protected override bool DoEvaluate()
        {
            foreach (BaseNode child in children)
            {
                if (child.Evaluate)
                {
                    if (_activeChild != null && _activeChild != child)
                    {
                        _activeChild.Clear();
                    }
                    _activeChild = child;
                    return true;
                }
            }

            if (_activeChild != null)
            {
                _activeChild.Clear();
                _activeChild = null;
            }

            return false;
        }

        public override void Clear()
        {
            if (_activeChild != null)
            {
                _activeChild.Clear();
                _activeChild = null;
            }

        }

        public override NodeResult Tick()
        {
            if (_activeChild == null)
            {
                return NodeResult.Ended;
            }

            NodeResult result = _activeChild.Tick();
            if (result != NodeResult.Running)
            {
                _activeChild.Clear();
                _activeChild = null;
            }
            return result;
        }
    }

}





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值