static void InitializeNodeHelper(UBTCompositeNode* ParentNode, UBTNode* NodeOb, uint8 TreeDepth, uint16& ExecutionIndex, TArray<FNodeInitializationData>& InitList, UBehaviorTree& TreeAsset, UObject* NodeOuter) { // special case: subtrees UBTTask_RunBehavior* SubtreeTask = Cast<UBTTask_RunBehavior>(NodeOb); if (SubtreeTask) { ExecutionIndex += SubtreeTask->GetInjectedNodesCount(); } InitList.Add(FNodeInitializationData(NodeOb, ParentNode, ExecutionIndex, TreeDepth, NodeOb->GetInstanceMemorySize(), NodeOb->GetSpecialMemorySize())); NodeOb->InitializeFromAsset(TreeAsset); ExecutionIndex++; UBTCompositeNode* CompositeOb = Cast<UBTCompositeNode>(NodeOb); if (CompositeOb) { for (int32 ServiceIndex = 0; ServiceIndex < CompositeOb->Services.Num(); ServiceIndex++) { if (CompositeOb->Services[ServiceIndex] == NULL) { UE_LOG(LogBehaviorTree, Warning, TEXT("%s has missing service node! (parent: %s)"), *TreeAsset.GetName(), *UBehaviorTreeTypes::DescribeNodeHelper(CompositeOb)); CompositeOb->Services.RemoveAt(ServiceIndex, 1, false); ServiceIndex--; continue; } UBTService* Service = Cast<UBTService>(StaticDuplicateObject(CompositeOb->Services[ServiceIndex], NodeOuter, TEXT("None")));; CompositeOb->Services[ServiceIndex] = Service; InitList.Add(FNodeInitializationData(Service, CompositeOb, ExecutionIndex, TreeDepth, Service->GetInstanceMemorySize(), Service->GetSpecialMemorySize())); Service->InitializeFromAsset(TreeAsset); ExecutionIndex++; } for (int32 ChildIndex = 0; ChildIndex < CompositeOb->Children.Num(); ChildIndex++) { FBTCompositeChild& ChildInfo = CompositeOb->Children[ChildIndex]; for (int32 DecoratorIndex = 0; DecoratorIndex < ChildInfo.Decorators.Num(); DecoratorIndex++) { if (ChildInfo.Decorators[DecoratorIndex] == NULL) { UE_LOG(LogBehaviorTree, Warning, TEXT("%s has missing decorator node! (parent: %s, branch: %d)"), *TreeAsset.GetName(), *UBehaviorTreeTypes::DescribeNodeHelper(CompositeOb), ChildIndex); ChildInfo.Decorators.RemoveAt(DecoratorIndex, 1, false); DecoratorIndex--; continue; } UBTDecorator* Decorator = Cast<UBTDecorator>(StaticDuplicateObject(ChildInfo.Decorators[DecoratorIndex], NodeOuter, TEXT("None"))); ChildInfo.Decorators[DecoratorIndex] = Decorator; InitList.Add(FNodeInitializationData(Decorator, CompositeOb, ExecutionIndex, TreeDepth, Decorator->GetInstanceMemorySize(), Decorator->GetSpecialMemorySize())); Decorator->InitializeFromAsset(TreeAsset); Decorator->InitializeDecorator(ChildIndex); ExecutionIndex++; } UBTNode* ChildNode = NULL; if (ChildInfo.ChildComposite) { ChildInfo.ChildComposite = Cast<UBTCompositeNode>(StaticDuplicateObject(ChildInfo.ChildComposite, NodeOuter, TEXT("None"))); ChildNode = ChildInfo.ChildComposite; } else if (ChildInfo.ChildTask) { ChildInfo.ChildTask = Cast<UBTTaskNode>(StaticDuplicateObject(ChildInfo.ChildTask, NodeOuter, TEXT("None"))); ChildNode = ChildInfo.ChildTask; } if (ChildNode) { InitializeNodeHelper(CompositeOb, ChildNode, TreeDepth + 1, ExecutionIndex, InitList, TreeAsset, NodeOuter); } } CompositeOb->InitializeComposite(ExecutionIndex - 1); } }