顺序节点: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();
}
}
}
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
}
}
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;
}
}
}