void UBehaviorTreeGraph::CreateBTFromGraph(UBehaviorTreeGraphNode* RootEdNode) { UBehaviorTree* BTAsset = Cast<UBehaviorTree>(GetOuter()); BTAsset->RootNode = NULL; //discard old tree // let's create new tree from graph uint16 ExecutionIndex = 0; uint8 TreeDepth = 0; BTAsset->RootNode = Cast<UBTCompositeNode>(RootEdNode->NodeInstance); if (BTAsset->RootNode) { BTAsset->RootNode->InitializeNode(NULL, ExecutionIndex, 0, TreeDepth); ExecutionIndex++; } // collect root level decorators uint16 DummyIndex = MAX_uint16; BTAsset->RootDecorators.Empty(); BTAsset->RootDecoratorOps.Empty(); BTGraphHelpers::CollectDecorators(BTAsset, RootEdNode, BTAsset->RootDecorators, BTAsset->RootDecoratorOps, false, NULL, &DummyIndex, 0, 0); // connect tree nodes BTGraphHelpers::CreateChildren(BTAsset, BTAsset->RootNode, RootEdNode, &ExecutionIndex, TreeDepth + 1); // mark root level nodes BTGraphHelpers::ClearRootLevelFlags(this); RootEdNode->bRootLevel = true; for (int32 Index = 0; Index < RootEdNode->Decorators.Num(); Index++) { UBehaviorTreeGraphNode* Node = RootEdNode->Decorators[Index]; if (Node) { Node->bRootLevel = true; } } if (BTAsset->RootNode) { BTAsset->RootNode->InitializeComposite(ExecutionIndex - 1); } // Now remove any orphaned nodes left behind after regeneration RemoveOrphanedNodes(); }
void UEnvironmentQueryGraph::UpdateAsset() { if (bLockUpdates) { return; } //let's find root node UEnvironmentQueryGraphNode_Root* RootNode = NULL; for (int32 Index = 0; Index < Nodes.Num(); ++Index) { RootNode = Cast<UEnvironmentQueryGraphNode_Root>(Nodes[Index]); if (RootNode != NULL) { break; } } UEnvQuery* Query = Cast<UEnvQuery>(GetOuter()); Query->Options.Reset(); if (RootNode && RootNode->Pins.Num() > 0 && RootNode->Pins[0]->LinkedTo.Num() > 0) { UEdGraphPin* MyPin = RootNode->Pins[0]; // sort connections so that they're organized the same as user can see in the editor MyPin->LinkedTo.Sort(FCompareNodeXLocation()); for (int32 Index=0; Index < MyPin->LinkedTo.Num(); ++Index) { UEnvironmentQueryGraphNode_Option* OptionNode = Cast<UEnvironmentQueryGraphNode_Option>(MyPin->LinkedTo[Index]->GetOwningNode()); if (OptionNode) { UEnvQueryOption* OptionInstance = Cast<UEnvQueryOption>(OptionNode->NodeInstance); if (OptionInstance != NULL) { OptionInstance->Tests.Reset(); for (int32 iTest = 0; iTest < OptionNode->Tests.Num(); iTest++) { UEnvironmentQueryGraphNode_Test* TestNode = OptionNode->Tests[iTest]; if (TestNode && TestNode->bTestEnabled) { UEnvQueryTest* TestInstance = Cast<UEnvQueryTest>(TestNode->NodeInstance); if (TestInstance) { OptionInstance->Tests.Add(TestInstance); } } } Query->Options.Add(OptionInstance); } } } } RemoveOrphanedNodes(); #if USE_EQS_DEBUGGER UEnvQueryManager::NotifyAssetUpdate(Query); #endif }
void UEnvironmentQueryGraph::UpdateAsset(int32 UpdateFlags) { if (IsLocked()) { return; } // let's find root node UEnvironmentQueryGraphNode_Root* RootNode = NULL; for (int32 Idx = 0; Idx < Nodes.Num(); Idx++) { RootNode = Cast<UEnvironmentQueryGraphNode_Root>(Nodes[Idx]); if (RootNode != NULL) { break; } } UEnvQuery* Query = Cast<UEnvQuery>(GetOuter()); Query->GetOptionsMutable().Reset(); if (RootNode && RootNode->Pins.Num() > 0 && RootNode->Pins[0]->LinkedTo.Num() > 0) { UEdGraphPin* MyPin = RootNode->Pins[0]; // sort connections so that they're organized the same as user can see in the editor MyPin->LinkedTo.Sort(FCompareNodeXLocation()); for (int32 Idx = 0; Idx < MyPin->LinkedTo.Num(); Idx++) { UEnvironmentQueryGraphNode_Option* OptionNode = Cast<UEnvironmentQueryGraphNode_Option>(MyPin->LinkedTo[Idx]->GetOwningNode()); if (OptionNode) { OptionNode->UpdateNodeData(); UEnvQueryOption* OptionInstance = Cast<UEnvQueryOption>(OptionNode->NodeInstance); if (OptionInstance && OptionInstance->Generator) { OptionInstance->Tests.Reset(); for (int32 TestIdx = 0; TestIdx < OptionNode->SubNodes.Num(); TestIdx++) { UAIGraphNode* SubNode = OptionNode->SubNodes[TestIdx]; if (SubNode == nullptr) { continue; } SubNode->ParentNode = OptionNode; UEnvironmentQueryGraphNode_Test* TestNode = Cast<UEnvironmentQueryGraphNode_Test>(SubNode); if (TestNode && TestNode->bTestEnabled) { UEnvQueryTest* TestInstance = Cast<UEnvQueryTest>(TestNode->NodeInstance); if (TestInstance) { OptionInstance->Tests.Add(TestInstance); } } } Query->GetOptionsMutable().Add(OptionInstance); } // FORT-16508 tracking BEGIN: log invalid option if (OptionInstance && OptionInstance->Generator == nullptr) { FString DebugMessage = FString::Printf(TEXT("[%s] UpdateAsset found option instance [pin:%d] without a generator! tests:%d"), FPlatformTime::StrTimestamp(), Idx, OptionNode->SubNodes.Num()); RootNode->LogDebugMessage(DebugMessage); } else if (OptionInstance == nullptr) { FString DebugMessage = FString::Printf(TEXT("[%s] UpdateAsset found option node [pin:%d] without an instance! tests:%d"), FPlatformTime::StrTimestamp(), Idx, OptionNode->SubNodes.Num()); RootNode->LogDebugMessage(DebugMessage); } // FORT-16508 tracking END } } } RemoveOrphanedNodes(); // FORT-16508 tracking BEGIN: find corrupted options if (RootNode) { for (int32 Idx = 0; Idx < Nodes.Num(); Idx++) { UEnvironmentQueryGraphNode_Option* OptionNode = Cast<UEnvironmentQueryGraphNode_Option>(Nodes[Idx]); if (OptionNode) { UEnvQueryOption* OptionInstance = Cast<UEnvQueryOption>(OptionNode->NodeInstance); if (OptionNode->NodeInstance == nullptr || OptionInstance == nullptr || OptionInstance->HasAnyFlags(RF_Transient)) { FString DebugMessage = FString::Printf(TEXT("[%s] found corrupted node after RemoveOrphanedNodes! type:instance option:%s instance:%d transient:%d tests:%d"), FPlatformTime::StrTimestamp(), *GetNameSafe(OptionNode), OptionNode->NodeInstance ? (OptionInstance ? 1 : -1) : 0, OptionNode->NodeInstance ? (OptionNode->HasAnyFlags(RF_Transient) ? 1 : 0) : -1, OptionNode->SubNodes.Num()); RootNode->LogDebugError(DebugMessage); } if (OptionInstance && (OptionInstance->Generator == nullptr || OptionInstance->Generator->HasAnyFlags(RF_Transient))) { FString DebugMessage = FString::Printf(TEXT("[%s] found corrupted node after RemoveOrphanedNodes! type:generator option:%s instance:%d transient:%d tests:%d"), FPlatformTime::StrTimestamp(), *GetNameSafe(OptionNode), OptionNode->NodeInstance ? 1 : 0, OptionNode->NodeInstance ? (OptionNode->HasAnyFlags(RF_Transient) ? 1 : 0) : -1, OptionNode->SubNodes.Num()); RootNode->LogDebugError(DebugMessage); } } } } // FORT-16508 tracking END #if USE_EQS_DEBUGGER UEnvQueryManager::NotifyAssetUpdate(Query); #endif }
void UEnvironmentQueryGraph::UpdateAsset(int32 UpdateFlags) { if (IsLocked()) { return; } // let's find root node UEnvironmentQueryGraphNode_Root* RootNode = NULL; for (int32 Idx = 0; Idx < Nodes.Num(); Idx++) { RootNode = Cast<UEnvironmentQueryGraphNode_Root>(Nodes[Idx]); if (RootNode != NULL) { break; } } UEnvQuery* Query = Cast<UEnvQuery>(GetOuter()); Query->Options.Reset(); if (RootNode && RootNode->Pins.Num() > 0 && RootNode->Pins[0]->LinkedTo.Num() > 0) { UEdGraphPin* MyPin = RootNode->Pins[0]; // sort connections so that they're organized the same as user can see in the editor MyPin->LinkedTo.Sort(FCompareNodeXLocation()); for (int32 Idx = 0; Idx < MyPin->LinkedTo.Num(); Idx++) { UEnvironmentQueryGraphNode_Option* OptionNode = Cast<UEnvironmentQueryGraphNode_Option>(MyPin->LinkedTo[Idx]->GetOwningNode()); if (OptionNode) { OptionNode->UpdateNodeData(); UEnvQueryOption* OptionInstance = Cast<UEnvQueryOption>(OptionNode->NodeInstance); if (OptionInstance && OptionInstance->Generator) { OptionInstance->Tests.Reset(); for (int32 TestIdx = 0; TestIdx < OptionNode->SubNodes.Num(); TestIdx++) { UAIGraphNode* SubNode = OptionNode->SubNodes[TestIdx]; if (SubNode == nullptr) { continue; } SubNode->ParentNode = OptionNode; UEnvironmentQueryGraphNode_Test* TestNode = Cast<UEnvironmentQueryGraphNode_Test>(SubNode); if (TestNode && TestNode->bTestEnabled) { UEnvQueryTest* TestInstance = Cast<UEnvQueryTest>(TestNode->NodeInstance); if (TestInstance) { OptionInstance->Tests.Add(TestInstance); } } } Query->Options.Add(OptionInstance); } } } } RemoveOrphanedNodes(); #if USE_EQS_DEBUGGER UEnvQueryManager::NotifyAssetUpdate(Query); #endif }