void UBehaviorTreeGraphNode::PostPlacedNewNode() { UClass* NodeClass = ClassData.GetClass(true); if (NodeClass) { UBehaviorTree* BT = Cast<UBehaviorTree>(GetBehaviorTreeGraph()->GetOuter()); if (BT) { NodeInstance = ConstructObject<UBTNode>(NodeClass, BT); UBTNode* BTNode = (UBTNode*)NodeInstance; BTNode->SetFlags(RF_Transactional); BTNode->InitializeFromAsset(*BT); BTNode->InitializeNode(NULL, MAX_uint16, 0, 0); } } }
void UBehaviorTreeGraph::RemoveOrphanedNodes() { UBehaviorTree* BTAsset = CastChecked<UBehaviorTree>(GetOuter()); // Obtain a list of all nodes that should be in the asset TSet<UBTNode*> AllNodes; for (int32 Index = 0; Index < Nodes.Num(); ++Index) { UBehaviorTreeGraphNode* MyNode = Cast<UBehaviorTreeGraphNode>(Nodes[Index]); if (MyNode) { UBTNode* MyNodeInstance = Cast<UBTNode>(MyNode->NodeInstance); if (MyNodeInstance) { AllNodes.Add(MyNodeInstance); } for (int32 iDecorator = 0; iDecorator < MyNode->Decorators.Num(); iDecorator++) { UBehaviorTreeGraphNode_CompositeDecorator* SubgraphNode = Cast<UBehaviorTreeGraphNode_CompositeDecorator>(MyNode->Decorators[iDecorator]); if (SubgraphNode) { TArray<UBTDecorator*> NodeInstances; TArray<FBTDecoratorLogic> DummyOps; SubgraphNode->CollectDecoratorData(NodeInstances, DummyOps); for (int32 SubIdx = 0; SubIdx < NodeInstances.Num(); SubIdx++) { AllNodes.Add(NodeInstances[SubIdx]); } } else { UBTNode* MyDecoratorNodeInstance = MyNode->Decorators[iDecorator] ? Cast<UBTNode>(MyNode->Decorators[iDecorator]->NodeInstance) : NULL; if (MyDecoratorNodeInstance) { AllNodes.Add(MyDecoratorNodeInstance); } } } for (int32 iService = 0; iService < MyNode->Services.Num(); iService++) { UBTNode* MyServiceNodeInstance = MyNode->Services[iService] ? Cast<UBTNode>(MyNode->Services[iService]->NodeInstance) : NULL; if (MyServiceNodeInstance) { AllNodes.Add(MyServiceNodeInstance); } } } } // Obtain a list of all nodes actually in the asset and discard unused nodes TArray<UObject*> AllInners; const bool bIncludeNestedObjects = false; GetObjectsWithOuter(BTAsset, AllInners, bIncludeNestedObjects); for (auto InnerIt = AllInners.CreateConstIterator(); InnerIt; ++InnerIt) { UBTNode* Node = Cast<UBTNode>(*InnerIt); if (Node && !AllNodes.Contains(Node)) { Node->SetFlags(RF_Transient); Node->Rename(NULL, GetTransientPackage(), REN_DontCreateRedirectors | REN_NonTransactional | REN_ForceNoResetLoaders); } } }