void UK2Node_LatentAbilityCall::PinDefaultValueChanged(UEdGraphPin* ChangedPin) { if (ChangedPin->PinName == FK2Node_LatentAbilityCallHelper::ClassPinName) { const UEdGraphSchema_K2* K2Schema = GetDefault<UEdGraphSchema_K2>(); // Because the archetype has changed, we break the output link as the output pin type will change //UEdGraphPin* ResultPin = GetResultPin(); //ResultPin->BreakAllPinLinks(); // Remove all pins related to archetype variables for (auto OldPin : SpawnParmPins) { OldPin->BreakAllPinLinks(); Pins.Remove(OldPin); } SpawnParmPins.Empty(); UClass* UseSpawnClass = GetClassToSpawn(); if (UseSpawnClass != NULL) { CreatePinsForClass(UseSpawnClass); } // Refresh the UI for the graph so the pin changes show up UEdGraph* Graph = GetGraph(); Graph->NotifyGraphChanged(); // Mark dirty FBlueprintEditorUtils::MarkBlueprintAsModified(GetBlueprint()); } }
// Moves the contents of all of the children graphs (recursively) into the target graph. This does not clone, it's destructive to the source void FEdGraphUtilities::MergeChildrenGraphsIn(UEdGraph* MergeTarget, UEdGraph* ParentGraph, bool bRequireSchemaMatch, bool bInIsCompiling/* = false*/) { // Determine if we are regenerating a blueprint on load UBlueprint* Blueprint = FBlueprintEditorUtils::FindBlueprintForGraph(MergeTarget); const bool bIsLoading = Blueprint ? Blueprint->bIsRegeneratingOnLoad : false; // Merge all children nodes in too for (int32 Index = 0; Index < ParentGraph->SubGraphs.Num(); ++Index) { UEdGraph* ChildGraph = ParentGraph->SubGraphs[Index]; auto NodeOwner = Cast<const UEdGraphNode>(ChildGraph ? ChildGraph->GetOuter() : nullptr); const bool bNonVirtualGraph = NodeOwner ? NodeOwner->ShouldMergeChildGraphs() : true; // Only merge children in with the same schema as the parent auto ChildSchema = ChildGraph ? ChildGraph->GetSchema() : nullptr; auto TargetSchema = MergeTarget ? MergeTarget->GetSchema() : nullptr; const bool bSchemaMatches = ChildSchema && TargetSchema && ChildSchema->GetClass()->IsChildOf(TargetSchema->GetClass()); const bool bDoMerge = bNonVirtualGraph && (!bRequireSchemaMatch || bSchemaMatches); if (bDoMerge) { // Even if we don't require a match to recurse, we do to actually copy the nodes if (bSchemaMatches) { ChildGraph->MoveNodesToAnotherGraph(MergeTarget, IsAsyncLoading() || bIsLoading, bInIsCompiling); } MergeChildrenGraphsIn(MergeTarget, ChildGraph, bRequireSchemaMatch, bInIsCompiling); } } }
void UK2Node_LiveEditObject::PinDefaultValueChanged(UEdGraphPin* Pin) { if(Pin->PinName == UK2Node_LiveEditObjectStatics::BaseClassPinName) { const UEdGraphSchema_K2* K2Schema = GetDefault<UEdGraphSchema_K2>(); // Remove all pins related to archetype variables TArray<UEdGraphPin*> OldPins = Pins; for(int32 i=0; i<OldPins.Num(); i++) { UEdGraphPin* OldPin = OldPins[i]; if( IsSpawnVarPin(OldPin) ) { Pin->BreakAllPinLinks(); Pins.Remove(OldPin); } } UClass* UseSpawnClass = GetClassToSpawn(); if(UseSpawnClass != NULL) { CreatePinsForClass(UseSpawnClass); } // Refresh the UI for the graph so the pin changes show up UEdGraph* Graph = GetGraph(); Graph->NotifyGraphChanged(); // Mark dirty FBlueprintEditorUtils::MarkBlueprintAsModified(GetBlueprint()); } }
void UAnimGraphNode_StateMachineBase::PostPlacedNewNode() { // Create a new animation graph check(EditorStateMachineGraph == NULL); EditorStateMachineGraph = CastChecked<UAnimationStateMachineGraph>(FBlueprintEditorUtils::CreateNewGraph(this, NAME_None, UAnimationStateMachineGraph::StaticClass(), UAnimationStateMachineSchema::StaticClass())); check(EditorStateMachineGraph); EditorStateMachineGraph->OwnerAnimGraphNode = this; // Find an interesting name TSharedPtr<INameValidatorInterface> NameValidator = FNameValidatorFactory::MakeValidator(this); FBlueprintEditorUtils::RenameGraphWithSuggestion(EditorStateMachineGraph, NameValidator, TEXT("New State Machine")); // Initialize the anim graph const UEdGraphSchema* Schema = EditorStateMachineGraph->GetSchema(); Schema->CreateDefaultNodesForGraph(*EditorStateMachineGraph); // Add the new graph as a child of our parent graph UEdGraph* ParentGraph = GetGraph(); if(ParentGraph->SubGraphs.Find(EditorStateMachineGraph) == INDEX_NONE) { ParentGraph->Modify(); ParentGraph->SubGraphs.Add(EditorStateMachineGraph); } }
FText UK2Node_MacroInstance::GetCompactNodeTitle() const { // Special case handling for standard macros // @TODO Change this to use metadata by allowing macros to specify CompactNodeTitle metadata UEdGraph* MacroGraph = MacroGraphReference.GetGraph(); if(MacroGraph != nullptr && MacroGraph->GetOuter()->GetName() == TEXT("StandardMacros")) { FName MacroName = FName(*MacroGraph->GetName()); if( MacroName == TEXT("IncrementFloat" ) || MacroName == TEXT("IncrementInt")) { return LOCTEXT("IncrementCompactNodeTitle", "++"); } else if( MacroName == TEXT("DecrementFloat") || MacroName == TEXT("DecrementInt")) { return LOCTEXT("DecrementCompactNodeTitle", "--"); } else if( MacroName == TEXT("NegateFloat") || MacroName == TEXT("NegateInt") ) { return LOCTEXT("DecrementCompactNodeTitle", "-"); } } return Super::GetCompactNodeTitle(); }
void FPersonaModule::OnNewBlueprintCreated(UBlueprint* InBlueprint) { if (ensure(InBlueprint->UbergraphPages.Num() > 0)) { UEdGraph* EventGraph = InBlueprint->UbergraphPages[0]; int32 SafeXPosition = 0; int32 SafeYPosition = 0; if (EventGraph->Nodes.Num() != 0) { SafeXPosition = EventGraph->Nodes[0]->NodePosX; SafeYPosition = EventGraph->Nodes[EventGraph->Nodes.Num() - 1]->NodePosY + EventGraph->Nodes[EventGraph->Nodes.Num() - 1]->NodeHeight + 100; } // add try get owner node UK2Node_CallFunction* GetOwnerNode = NewObject<UK2Node_CallFunction>(EventGraph); UFunction* MakeNodeFunction = UAnimInstance::StaticClass()->FindFunctionByName(GET_FUNCTION_NAME_CHECKED(UAnimInstance, TryGetPawnOwner)); GetOwnerNode->CreateNewGuid(); GetOwnerNode->PostPlacedNewNode(); GetOwnerNode->SetFromFunction(MakeNodeFunction); GetOwnerNode->SetFlags(RF_Transactional); GetOwnerNode->AllocateDefaultPins(); GetOwnerNode->NodePosX = SafeXPosition; GetOwnerNode->NodePosY = SafeYPosition; UEdGraphSchema_K2::SetNodeMetaData(GetOwnerNode, FNodeMetadata::DefaultGraphNode); GetOwnerNode->bIsNodeEnabled = false; EventGraph->AddNode(GetOwnerNode); } }
UK2Node_PlayMovieScene* FSequencerActorBindingManager::CreateNewPlayMovieSceneNode( UMovieScene* MovieScene ) const { // Grab the world object for this editor check( MovieScene != NULL ); ULevel* Level = ActorWorld->GetCurrentLevel(); check( Level != NULL ); // Here, we'll create a level script if one does not yet exist. const bool bDontCreate = false; ULevelScriptBlueprint* LSB = Level->GetLevelScriptBlueprint( bDontCreate ); if( LSB != NULL ) { UEdGraph* TargetGraph = NULL; if( LSB->UbergraphPages.Num() > 0 ) { TargetGraph = LSB->UbergraphPages[0]; // Just use the first graph } if( ensure( TargetGraph != NULL ) ) { // Figure out a decent place to stick the node const FVector2D NewNodePos = TargetGraph->GetGoodPlaceForNewNode(); // Create a new node UK2Node_PlayMovieScene* TemplateNode = NewObject<UK2Node_PlayMovieScene>(); TemplateNode->SetMovieScene( MovieScene ); return FEdGraphSchemaAction_K2NewNode::SpawnNodeFromTemplate<UK2Node_PlayMovieScene>(TargetGraph, TemplateNode, NewNodePos);; } } return NULL; }
bool SGraphPin::TryHandlePinConnection(SGraphPin& OtherSPin) { UEdGraphPin* PinA = GetPinObj(); UEdGraphPin* PinB = OtherSPin.GetPinObj(); UEdGraph* MyGraphObj = PinA->GetOwningNode()->GetGraph(); return MyGraphObj->GetSchema()->TryCreateConnection(PinA, PinB); }
FText UK2Node_FunctionEntry::GetNodeTitle(ENodeTitleType::Type TitleType) const { UEdGraph* Graph = GetGraph(); FGraphDisplayInfo DisplayInfo; Graph->GetSchema()->GetGraphDisplayInformation(*Graph, DisplayInfo); return DisplayInfo.DisplayName; }
void UEdGraphNode::DestroyNode() { UEdGraph* ParentGraph = GetGraph(); check(ParentGraph); // Remove the node - this will break all links. Will be GC'd after this. ParentGraph->RemoveNode(this); }
FString UK2Node_MacroInstance::GetDocumentationExcerptName() const { UEdGraph* MacroGraph = MacroGraphReference.GetGraph(); if (MacroGraph != NULL) { return MacroGraph->GetName(); } return Super::GetDocumentationExcerptName(); }
void UAnimationConduitGraphSchema::GetGraphDisplayInformation(const UEdGraph& Graph, /*out*/ FGraphDisplayInfo& DisplayInfo) const { DisplayInfo.DisplayName = FText::FromString( Graph.GetName() ); if (const UAnimStateConduitNode* ConduitNode = Cast<const UAnimStateConduitNode>(Graph.GetOuter())) { DisplayInfo.DisplayName = FText::Format( NSLOCTEXT("Animation", "ConduitRuleGraphTitle", "{0} (conduit rule)"), FText::FromString( ConduitNode->GetNodeTitle(ENodeTitleType::FullTitle) ) ); } }
void FBlueprintStatsModule::DumpBlueprintStats() { TArray<FBlueprintStatRecord> Records; for (TObjectIterator<UBlueprint> BlueprintIt; BlueprintIt; ++BlueprintIt) { UBlueprint* Blueprint = *BlueprintIt; new (Records) FBlueprintStatRecord(Blueprint); } // Now merge them FBlueprintStatRecord Aggregate(NULL); for (const FBlueprintStatRecord& SourceRecord : Records) { Aggregate.MergeAnotherRecordIn(SourceRecord); } // Sort the lists Aggregate.NodeCount.ValueSort(TGreater<int32>()); Aggregate.FunctionCount.ValueSort(TGreater<int32>()); Aggregate.FunctionOwnerCount.ValueSort(TGreater<int32>()); Aggregate.RemoteMacroCount.ValueSort(TGreater<int32>()); // Print out the merged record UE_LOG(LogBlueprintStats, Log, TEXT("Blueprint stats for %d blueprints in %s"), Records.Num(), GGameName); UE_LOG(LogBlueprintStats, Log, TEXT("%s"), *Aggregate.ToString(true)); UE_LOG(LogBlueprintStats, Log, TEXT("%s"), *Aggregate.ToString(false)); UE_LOG(LogBlueprintStats, Log, TEXT("\n")); // Print out the node list UE_LOG(LogBlueprintStats, Log, TEXT("NodeClass,NumInstances")); for (const auto& NodePair : Aggregate.NodeCount) { UE_LOG(LogBlueprintStats, Log, TEXT("%s,%d"), *(NodePair.Key->GetName()), NodePair.Value); } UE_LOG(LogBlueprintStats, Log, TEXT("\n")); // Print out the function list UE_LOG(LogBlueprintStats, Log, TEXT("FunctionPath,ClassName,FunctionName,NumInstances")); for (const auto& FunctionPair : Aggregate.FunctionCount) { UFunction* Function = FunctionPair.Key; UE_LOG(LogBlueprintStats, Log, TEXT("%s,%s,%s,%d"), *(Function->GetPathName()), *(Function->GetOuterUClass()->GetName()), *(Function->GetName()), FunctionPair.Value); } UE_LOG(LogBlueprintStats, Log, TEXT("\n")); // Print out the macro list UE_LOG(LogBlueprintStats, Log, TEXT("MacroPath,MacroName,NumInstances")); for (const auto& MacroPair : Aggregate.RemoteMacroCount) { UEdGraph* MacroGraph = MacroPair.Key; UE_LOG(LogBlueprintStats, Log, TEXT("%s,%s,%d"), *(MacroGraph->GetPathName()), *(MacroGraph->GetName()), MacroPair.Value); } UE_LOG(LogBlueprintStats, Log, TEXT("\n")); }
void UK2Node_SpawnActorFromClass::OnClassPinChanged() { const UEdGraphSchema_K2* K2Schema = GetDefault<UEdGraphSchema_K2>(); // Remove all pins related to archetype variables TArray<UEdGraphPin*> OldPins = Pins; TArray<UEdGraphPin*> OldClassPins; for (int32 i = 0; i < OldPins.Num(); i++) { UEdGraphPin* OldPin = OldPins[i]; if (IsSpawnVarPin(OldPin)) { Pins.Remove(OldPin); OldClassPins.Add(OldPin); } } CachedNodeTitle.MarkDirty(); UClass* UseSpawnClass = GetClassToSpawn(); TArray<UEdGraphPin*> NewClassPins; if (UseSpawnClass != NULL) { CreatePinsForClass(UseSpawnClass, NewClassPins); } UEdGraphPin* ResultPin = GetResultPin(); // Cache all the pin connections to the ResultPin, we will attempt to recreate them TArray<UEdGraphPin*> ResultPinConnectionList = ResultPin->LinkedTo; // Because the archetype has changed, we break the output link as the output pin type will change ResultPin->BreakAllPinLinks(); // Recreate any pin links to the Result pin that are still valid for (UEdGraphPin* Connections : ResultPinConnectionList) { K2Schema->TryCreateConnection(ResultPin, Connections); } K2Schema->ConstructBasicPinTooltip(*ResultPin, LOCTEXT("ResultPinDescription", "The spawned Actor"), ResultPin->PinToolTip); // Rewire the old pins to the new pins so connections are maintained if possible RewireOldPinsToNewPins(OldClassPins, NewClassPins); // Destroy the old pins DestroyPinList(OldClassPins); // Refresh the UI for the graph so the pin changes show up UEdGraph* Graph = GetGraph(); Graph->NotifyGraphChanged(); // Mark dirty FBlueprintEditorUtils::MarkBlueprintAsModified(GetBlueprint()); }
FText UK2Node_MacroInstance::GetNodeTitle(ENodeTitleType::Type TitleType) const { UEdGraph* MacroGraph = MacroGraphReference.GetGraph(); FText Result = NSLOCTEXT("K2Node", "MacroInstance", "Macro instance"); if (MacroGraph) { Result = FText::FromString(MacroGraph->GetName()); } return Result; }
void UAnimationStateGraphSchema::GetGraphDisplayInformation(const UEdGraph& Graph, /*out*/ FGraphDisplayInfo& DisplayInfo) const { DisplayInfo.PlainName = FText::FromString( Graph.GetName() ); if (const UAnimStateNode* StateNode = Cast<const UAnimStateNode>(Graph.GetOuter())) { DisplayInfo.PlainName = FText::Format( LOCTEXT("StateNameGraphTitle", "{0} (state)"), FText::FromString( StateNode->GetStateName() ) ); } DisplayInfo.DisplayName = DisplayInfo.PlainName; }
void UEdGraph::GetAllChildrenGraphs(TArray<UEdGraph*>& Graphs) const { #if WITH_EDITORONLY_DATA for (int32 i = 0; i < SubGraphs.Num(); ++i) { UEdGraph* Graph = SubGraphs[i]; checkf(Graph, *FString::Printf(TEXT("%s has invalid SubGraph array entry at %d"), *GetFullName(), i)); Graphs.Add(Graph); Graph->GetAllChildrenGraphs(Graphs); } #endif // WITH_EDITORONLY_DATA }
void UAnimGraphNode_StateMachineBase::DestroyNode() { UEdGraph* GraphToRemove = EditorStateMachineGraph; EditorStateMachineGraph = NULL; Super::DestroyNode(); if (GraphToRemove) { UBlueprint* Blueprint = GetBlueprint(); GraphToRemove->Modify(); FBlueprintEditorUtils::RemoveGraph(Blueprint, GraphToRemove, EGraphRemoveFlags::Recompile); } }
void UAnimationConduitGraphSchema::GetGraphDisplayInformation(const UEdGraph& Graph, /*out*/ FGraphDisplayInfo& DisplayInfo) const { DisplayInfo.PlainName = FText::FromString( Graph.GetName() ); if (const UAnimStateConduitNode* ConduitNode = Cast<const UAnimStateConduitNode>(Graph.GetOuter())) { FFormatNamedArguments Args; Args.Add(TEXT("NodeTitle"), ConduitNode->GetNodeTitle(ENodeTitleType::FullTitle) ); DisplayInfo.PlainName = FText::Format( NSLOCTEXT("Animation", "ConduitRuleGraphTitle", "{NodeTitle} (conduit rule)"), Args); } DisplayInfo.DisplayName = DisplayInfo.PlainName; }
void UBlueprint::GetAllGraphs(TArray<UEdGraph*>& Graphs) const { #if WITH_EDITORONLY_DATA for (int32 i = 0; i < FunctionGraphs.Num(); ++i) { UEdGraph* Graph = FunctionGraphs[i]; Graphs.Add(Graph); Graph->GetAllChildrenGraphs(Graphs); } for (int32 i = 0; i < MacroGraphs.Num(); ++i) { UEdGraph* Graph = MacroGraphs[i]; Graphs.Add(Graph); Graph->GetAllChildrenGraphs(Graphs); } for (int32 i = 0; i < UbergraphPages.Num(); ++i) { UEdGraph* Graph = UbergraphPages[i]; Graphs.Add(Graph); Graph->GetAllChildrenGraphs(Graphs); } for (int32 BPIdx=0; BPIdx<ImplementedInterfaces.Num(); BPIdx++) { const FBPInterfaceDescription& InterfaceDesc = ImplementedInterfaces[BPIdx]; for (int32 GraphIdx = 0; GraphIdx < InterfaceDesc.Graphs.Num(); GraphIdx++) { UEdGraph* Graph = InterfaceDesc.Graphs[GraphIdx]; Graphs.Add(Graph); Graph->GetAllChildrenGraphs(Graphs); } } #endif // WITH_EDITORONLY_DATA }
void UK2Node_MacroInstance::AllocateDefaultPins() { UK2Node::AllocateDefaultPins(); PreloadObject(MacroGraphReference.GetBlueprint()); UEdGraph* MacroGraph = MacroGraphReference.GetGraph(); if (MacroGraph != NULL) { PreloadObject(MacroGraph); // Preload the macro graph, if needed, so that we can get the proper pins if (MacroGraph->HasAnyFlags(RF_NeedLoad)) { PreloadObject(MacroGraph); FBlueprintEditorUtils::PreloadMembers(MacroGraph); } for (TArray<UEdGraphNode*>::TIterator NodeIt(MacroGraph->Nodes); NodeIt; ++NodeIt) { if (UK2Node_Tunnel* TunnelNode = Cast<UK2Node_Tunnel>(*NodeIt)) { // Only want exact tunnel nodes, more specific nodes like composites or macro instances shouldn't be grabbed. if (TunnelNode->GetClass() == UK2Node_Tunnel::StaticClass()) { for (TArray<UEdGraphPin*>::TIterator PinIt(TunnelNode->Pins); PinIt; ++PinIt) { UEdGraphPin* PortPin = *PinIt; // We're not interested in any pins that have been expanded internally on the macro if (PortPin->ParentPin == NULL) { UEdGraphPin* NewLocalPin = CreatePin( UEdGraphPin::GetComplementaryDirection(PortPin->Direction), PortPin->PinType.PinCategory, PortPin->PinType.PinSubCategory, PortPin->PinType.PinSubCategoryObject.Get(), PortPin->PinType.bIsArray, PortPin->PinType.bIsReference, PortPin->PinName); NewLocalPin->DefaultValue = NewLocalPin->AutogeneratedDefaultValue = PortPin->DefaultValue; } } } } } } }
FReply FDragConnection::DroppedOnPin(FVector2D ScreenPosition, FVector2D GraphPosition) { TArray<UEdGraphPin*> ValidSourcePins; ValidateGraphPinList(/*out*/ ValidSourcePins); const FScopedTransaction Transaction( NSLOCTEXT("UnrealEd", "GraphEd_CreateConnection", "Create Pin Link") ); UEdGraphPin* PinB = GetHoveredPin(); bool bError = false; TSet<UEdGraphNode*> NodeList; for (UEdGraphPin* PinA : ValidSourcePins) { if ((PinA != NULL) && (PinB != NULL)) { UEdGraph* MyGraphObj = PinA->GetOwningNode()->GetGraph(); if (MyGraphObj->GetSchema()->TryCreateConnection(PinA, PinB)) { NodeList.Add(PinA->GetOwningNode()); NodeList.Add(PinB->GetOwningNode()); } } else { bError = true; } } // Send all nodes that received a new pin connection a notification for (auto It = NodeList.CreateConstIterator(); It; ++It) { UEdGraphNode* Node = (*It); Node->NodeConnectionListChanged(); } if (bError) { return FReply::Unhandled(); } return FReply::Handled(); }
// Clones the content from SourceGraph and merges it into MergeTarget; including merging/flattening all of the children from the SourceGraph into MergeTarget void FEdGraphUtilities::CloneAndMergeGraphIn(UEdGraph* MergeTarget, UEdGraph* SourceGraph, FCompilerResultsLog& MessageLog, bool bRequireSchemaMatch, bool bInIsCompiling/* = false*/, TArray<UEdGraphNode*>* OutClonedNodes) { // Clone the graph, then move all of it's children UEdGraph* ClonedGraph = CloneGraph(SourceGraph, NULL, &MessageLog, true); MergeChildrenGraphsIn(ClonedGraph, ClonedGraph, bRequireSchemaMatch); // Duplicate the list of cloned nodes if (OutClonedNodes != NULL) { OutClonedNodes->Append(ClonedGraph->Nodes); } // Determine if we are regenerating a blueprint on load UBlueprint* Blueprint = FBlueprintEditorUtils::FindBlueprintForGraph(MergeTarget); const bool bIsLoading = Blueprint ? Blueprint->bIsRegeneratingOnLoad : false; // Move them all to the destination ClonedGraph->MoveNodesToAnotherGraph(MergeTarget, IsAsyncLoading() || bIsLoading, bInIsCompiling); }
FName UK2Node_MacroInstance::GetPaletteIcon(FLinearColor& OutColor) const { // Special case handling for standard macros // @TODO Change this to a SlateBurushAsset pointer on the graph or something similar, to allow any macro to have an icon UEdGraph* MacroGraph = MacroGraphReference.GetGraph(); if(MacroGraph != NULL && MacroGraph->GetOuter()->GetName() == TEXT("StandardMacros")) { FName MacroName = FName(*MacroGraph->GetName()); if( MacroName == TEXT("ForLoop" ) || MacroName == TEXT("ForLoopWithBreak") || MacroName == TEXT("WhileLoop") ) { return TEXT("GraphEditor.Macro.Loop_16x"); } else if( MacroName == TEXT("Gate") ) { return TEXT("GraphEditor.Macro.Gate_16x"); } else if( MacroName == TEXT("Do N") ) { return TEXT("GraphEditor.Macro.DoN_16x"); } else if (MacroName == TEXT("DoOnce")) { return TEXT("GraphEditor.Macro.DoOnce_16x"); } else if (MacroName == TEXT("IsValid")) { return TEXT("GraphEditor.Macro.IsValid_16x"); } else if (MacroName == TEXT("FlipFlop")) { return TEXT("GraphEditor.Macro.FlipFlop_16x"); } else if ( MacroName == TEXT("ForEachLoop") || MacroName == TEXT("ForEachLoopWithBreak") ) { return TEXT("GraphEditor.Macro.ForEach_16x"); } } return TEXT("GraphEditor.Macro_16x"); }
bool UK2Node_Composite::IsCompositeNameAvailable( const FString& NewName ) { UEdGraph* ParentGraph = CastChecked<UEdGraph>(GetOuter()); //check to see if the parent graph already has a sub graph by this name for (auto It = ParentGraph->SubGraphs.CreateIterator();It;++It) { UEdGraph* Graph = *It; if (Graph->GetName() == NewName) { return false; } } if (UK2Node_Composite* Composite = Cast<UK2Node_Composite>(ParentGraph->GetOuter())) { return Composite->IsCompositeNameAvailable(NewName); } return true; }
void UAnimationCustomTransitionSchema::GetGraphDisplayInformation(const UEdGraph& Graph, /*out*/ FGraphDisplayInfo& DisplayInfo) const { DisplayInfo.PlainName = FText::FromString( Graph.GetName() ); if (const UAnimStateTransitionNode* TransNode = Cast<const UAnimStateTransitionNode>(Graph.GetOuter())) { DisplayInfo.PlainName = FText::Format( NSLOCTEXT("Animation", "CustomBlendGraphTitle", "{0} (custom blend)"), TransNode->GetNodeTitle(ENodeTitleType::FullTitle) ); } DisplayInfo.DisplayName = DisplayInfo.PlainName; }
/** * Takes two blueprints and compares them (as if we were running the in-editor * diff tool). Any discrepancies between the two graphs will be listed in the DiffsOut array. * * @param LhsBlueprint The baseline blueprint you wish to compare against. * @param RhsBlueprint The blueprint you wish to look for changes in. * @param DiffsOut An output list that will contain any graph internal differences that were found. * @return True if the two blueprints differ, false if they are identical. */ static bool DiffBlueprints(UBlueprint* const LhsBlueprint, UBlueprint* const RhsBlueprint, TArray<FDiffSingleResult>& DiffsOut) { TArray<UEdGraph*> LhsGraphs; LhsBlueprint->GetAllGraphs(LhsGraphs); TArray<UEdGraph*> RhsGraphs; RhsBlueprint->GetAllGraphs(RhsGraphs); bool bDiffsFound = false; // walk the graphs in the rhs blueprint (because, conceptually, it is the more up to date one) for (auto RhsGraphIt(RhsGraphs.CreateIterator()); RhsGraphIt; ++RhsGraphIt) { UEdGraph* RhsGraph = *RhsGraphIt; UEdGraph* LhsGraph = NULL; // search for the corresponding graph in the lhs blueprint for (auto LhsGraphIt(LhsGraphs.CreateIterator()); LhsGraphIt; ++LhsGraphIt) { // can't trust the guid until we've done a resave on every asset //if ((*LhsGraphIt)->GraphGuid == RhsGraph->GraphGuid) // name compares is probably sufficient, but just so we don't always do a string compare if (((*LhsGraphIt)->GetClass() == RhsGraph->GetClass()) && ((*LhsGraphIt)->GetName() == RhsGraph->GetName())) { LhsGraph = *LhsGraphIt; break; } } // if a matching graph wasn't found in the lhs blueprint, then that is a BIG inconsistency if (LhsGraph == NULL) { bDiffsFound = true; continue; } bDiffsFound |= FGraphDiffControl::DiffGraphs(LhsGraph, RhsGraph, DiffsOut); } return bDiffsFound; }
void FScriptBlueprintCompiler::CreateScriptDefinedFunction(FScriptField& Field) { check(ContextProperty); UScriptBlueprint* Blueprint = ScriptBlueprint(); const FString FunctionName = Field.Name.ToString(); // Create Blueprint Graph which consists of 3 nodes: 'Entry', 'Get Script Context' and 'Call Function' // @todo: once we figure out how to get parameter lists for functions we can add suport for that here UEdGraph* ScriptFunctionGraph = NewObject<UEdGraph>(Blueprint, *FString::Printf(TEXT("%s_Graph"), *FunctionName)); ScriptFunctionGraph->Schema = UEdGraphSchema_K2::StaticClass(); ScriptFunctionGraph->SetFlags(RF_Transient); FKismetFunctionContext* FunctionContext = CreateFunctionContext(); FunctionContext->SourceGraph = ScriptFunctionGraph; FunctionContext->bCreateDebugData = false; UK2Node_FunctionEntry* EntryNode = SpawnIntermediateNode<UK2Node_FunctionEntry>(NULL, ScriptFunctionGraph); EntryNode->CustomGeneratedFunctionName = Field.Name; EntryNode->AllocateDefaultPins(); UK2Node_VariableGet* GetVariableNode = SpawnIntermediateNode<UK2Node_VariableGet>(NULL, ScriptFunctionGraph); GetVariableNode->VariableReference.SetSelfMember(ContextProperty->GetFName()); GetVariableNode->AllocateDefaultPins(); UK2Node_CallFunction* CallFunctionNode = SpawnIntermediateNode<UK2Node_CallFunction>(NULL, ScriptFunctionGraph); CallFunctionNode->FunctionReference.SetExternalMember(TEXT("CallScriptFunction"), ContextProperty->PropertyClass); CallFunctionNode->AllocateDefaultPins(); UEdGraphPin* FunctionNamePin = CallFunctionNode->FindPinChecked(TEXT("FunctionName")); FunctionNamePin->DefaultValue = FunctionName; // Link nodes together UEdGraphPin* ExecPin = Schema->FindExecutionPin(*EntryNode, EGPD_Output); UEdGraphPin* GetVariableOutPin = GetVariableNode->FindPinChecked(ContextProperty->GetName()); UEdGraphPin* CallFunctionPin = Schema->FindExecutionPin(*CallFunctionNode, EGPD_Input); UEdGraphPin* FunctionTargetPin = CallFunctionNode->FindPinChecked(TEXT("self")); ExecPin->MakeLinkTo(CallFunctionPin); GetVariableOutPin->MakeLinkTo(FunctionTargetPin); }
void UEnvironmentQueryGraphNode_Option::PostPlacedNewNode() { UClass* NodeClass = ClassData.GetClass(true); if (NodeClass) { UEdGraph* MyGraph = GetGraph(); UObject* GraphOwner = MyGraph ? MyGraph->GetOuter() : nullptr; if (GraphOwner) { UEnvQueryOption* QueryOption = NewObject<UEnvQueryOption>(GraphOwner); QueryOption->Generator = NewObject<UEnvQueryGenerator>(GraphOwner, NodeClass); QueryOption->Generator->UpdateNodeVersion(); QueryOption->SetFlags(RF_Transactional); QueryOption->Generator->SetFlags(RF_Transactional); NodeInstance = QueryOption; InitializeInstance(); } } }
void UK2Node_SpawnActor::PinDefaultValueChanged(UEdGraphPin* ChangedPin) { if (ChangedPin->PinName == BlueprintPinName) { const UEdGraphSchema_K2* K2Schema = GetDefault<UEdGraphSchema_K2>(); // Because the archetype has changed, we break the output link as the output pin type will change UEdGraphPin* ResultPin = GetResultPin(); ResultPin->BreakAllPinLinks(); // Remove all pins related to archetype variables TArray<UEdGraphPin*> OldPins = Pins; for (int32 i = 0; i < OldPins.Num(); i++) { UEdGraphPin* OldPin = OldPins[i]; if (IsSpawnVarPin(OldPin)) { OldPin->BreakAllPinLinks(); Pins.Remove(OldPin); } } CachedNodeTitle.MarkDirty(); UClass* UseSpawnClass = GetClassToSpawn(); if(UseSpawnClass != NULL) { CreatePinsForClass(UseSpawnClass); } // Refresh the UI for the graph so the pin changes show up UEdGraph* Graph = GetGraph(); Graph->NotifyGraphChanged(); // Mark dirty FBlueprintEditorUtils::MarkBlueprintAsModified(GetBlueprint()); } }