行为树的开始执行的流程图:
一,执行流程
UBehaviorTreeComponent:处理行为树的执行逻辑;
- StartTree()行为树执行入口;
1,PushInstance() 调用UBehaviorTreeManager 中的LoadTree加载资源;创建新的FBehaviorTreeInstance行为树实例 调用FBehaviorTreeInstance::Initialize()初始化函数,初始化了内存以及节点的实例,将NewInstance加入InstanceStack数据中,调用RequestExecution();
2,RequestExecution() 有三个重载函数,会根据任务结束,装饰器事件,产生新的请求事件赋值给成员变量 ExecutionRequest,并且开启Tick中ProcessExecutionRequest的执行;
3,ProcessExecutionRequest:执行ExecutionRequest请求,比如一开始请求执行根节点,这里会搜索行为树找到可执行的task,然后将其中节点涉及到的axunode,都存在SearchData中;下面是执行的主要代码,搜索树,直到找到下一个可执行的Task;FindChildToExecute寻找可在执行节点时候还将更新新的分支的添加service以及decorator,删除旧的没有被激活分支Service,decorator节点这些信息会存在searchData.pendingupdates中其中包含了是移除还是添加的区分;
// start looking for next task
while (TestNode && NextTask == NULL)
{
BT_SEARCHLOG(SearchData, Verbose, TEXT("Testing node: %s"), *UBehaviorTreeTypes::DescribeNodeHelper(TestNode));
const int32 ChildBranchIdx = TestNode->FindChildToExecute(SearchData, NodeResult);
UBTNode* StoreNode = TestNode;
if (SearchData.bPostponeSearch)
{
// break out of current search loop
TestNode = NULL;
bIsSearchValid = false;
}
else if (ChildBranchIdx == BTSpecialChild::ReturnToParent)
{
UBTCompositeNode* ChildNode = TestNode;
TestNode = TestNode->GetParentNode();
// does it want to move up the tree?
if (TestNode == NULL)
{
// special case for leaving instance: deactivate root manually
ChildNode->OnNodeDeactivation(SearchData, NodeResult);
// don't remove top instance from stack, so it could be looped
if (ActiveInstanceIdx > 0)
{
StoreDebuggerSearchStep(InstanceStack[ActiveInstanceIdx].ActiveNode, ActiveInstanceIdx, NodeResult);
StoreDebuggerRemovedInstance(ActiveInstanceIdx);
InstanceStack[ActiveInstanceIdx].DeactivateNodes(SearchData, ActiveInstanceIdx);
// store notify for later use if search is not reverted
SearchData.PendingNotifies.Add(FBehaviorTreeSearchUpdateNotify(ActiveInstanceIdx, NodeResult));
// and leave subtree
ActiveInstanceIdx--;
StoreDebuggerSearchStep(InstanceStack[ActiveInstanceIdx].ActiveNode, ActiveInstanceIdx, NodeResult);
TestNode = InstanceStack[ActiveInstanceIdx].ActiveNode->GetParentNode();
}
}
if (TestNode)
{
TestNode->OnChildDeactivation(SearchData, *ChildNode, NodeResult);
}
}
else if (TestNode->Children.IsValidIndex(ChildBranchIdx))
{
// was new task found?
NextTask = TestNode->Children[ChildBranchIdx].ChildTask;
// or it wants to move down the tree?
TestNode = TestNode->Children[ChildBranchIdx].ChildComposite;
}
// store afte