FReply FKismetVariableDragDropAction::DroppedOnNode(FVector2D ScreenPosition, FVector2D GraphPosition) { UK2Node_Variable* TargetNode = Cast<UK2Node_Variable>(GetHoveredNode()); if (TargetNode && (VariableName != TargetNode->GetVarName())) { const FScopedTransaction Transaction( LOCTEXT("ReplacePinVariable", "Replace Pin Variable") ); UProperty* VariableProperty = GetVariableProperty(); if(CanVariableBeDropped(VariableProperty, *TargetNode->GetGraph())) { const FString OldVarName = TargetNode->GetVarNameString(); const UEdGraphSchema_K2* Schema = Cast<const UEdGraphSchema_K2>(TargetNode->GetSchema()); TArray<class UEdGraphPin*> BadLinks; GetLinksThatWillBreak(TargetNode,VariableProperty,BadLinks); // Change the variable name and context UBlueprint* DropOnBlueprint = FBlueprintEditorUtils::FindBlueprintForGraph(TargetNode->GetGraph()); UEdGraphPin* Pin = TargetNode->FindPin(OldVarName); DropOnBlueprint->Modify(); TargetNode->Modify(); if (Pin != NULL) { Pin->Modify(); } UEdGraphSchema_K2::ConfigureVarNode(TargetNode, VariableName, VariableSource.Get(), DropOnBlueprint); if ((Pin == NULL) || (Pin->LinkedTo.Num() == BadLinks.Num()) || (Schema == NULL)) { TargetNode->GetSchema()->ReconstructNode(*TargetNode); } else { FEdGraphPinType NewPinType; Schema->ConvertPropertyToPinType(VariableProperty,NewPinType); Pin->PinName = VariableName.ToString(); Pin->PinType = NewPinType; //break bad links for(TArray<class UEdGraphPin*>::TIterator OtherPinIt(BadLinks);OtherPinIt;) { Pin->BreakLinkTo(*OtherPinIt); } } return FReply::Handled(); } } return FReply::Unhandled(); }
void UK2Node_AddComponent::DestroyNode() { // See if this node has a template UActorComponent* Template = GetTemplateFromNode(); if (Template != NULL) { // Get the blueprint so we can remove it from it UBlueprint* BlueprintObj = GetBlueprint(); // remove it BlueprintObj->Modify(); BlueprintObj->ComponentTemplates.Remove(Template); } Super::DestroyNode(); }
void UK2Node_AddComponent::DestroyNode() { // See if this node has a template UActorComponent* Template = GetTemplateFromNode(); if (Template != NULL) { // Save current template state - this is needed in order to ensure that we restore to the correct Outer in the case of a compile prior to the undo/redo action. Template->Modify(); // Get the blueprint so we can remove it from it UBlueprint* BlueprintObj = GetBlueprint(); // remove it BlueprintObj->Modify(); BlueprintObj->ComponentTemplates.Remove(Template); } Super::DestroyNode(); }
void UK2Node_Timeline::PostPasteNode() { Super::PostPasteNode(); UBlueprint* Blueprint = GetBlueprint(); check(Blueprint); UTimelineTemplate* OldTimeline = NULL; //find the template with same UUID for(TObjectIterator<UTimelineTemplate> It;It;++It) { UTimelineTemplate* Template = *It; if(Template->TimelineGuid == TimelineGuid) { OldTimeline = Template; break; } } // Make sure TimelineName is unique, and we allocate a new timeline template object for this node TimelineName = FBlueprintEditorUtils::FindUniqueTimelineName(Blueprint); if(!OldTimeline) { if (UTimelineTemplate* Template = FBlueprintEditorUtils::AddNewTimeline(Blueprint, TimelineName)) { bAutoPlay = Template->bAutoPlay; bLoop = Template->bLoop; } } else { check(NULL != Blueprint->GeneratedClass); Blueprint->Modify(); const FName TimelineTemplateName = *UTimelineTemplate::TimelineVariableNameToTemplateName(TimelineName); UTimelineTemplate* Template = DuplicateObject<UTimelineTemplate>(OldTimeline, Blueprint->GeneratedClass, *TimelineTemplateName.ToString()); bAutoPlay = Template->bAutoPlay; bLoop = Template->bLoop; Template->SetFlags(RF_Transactional); Blueprint->Timelines.Add(Template); // Fix up timeline tracks to point to the proper location. When duplicated, they're still parented to their old blueprints because we don't have the appropriate scope. Note that we never want to fix up external curve asset references { for( auto TrackIt = Template->FloatTracks.CreateIterator(); TrackIt; ++TrackIt ) { FTTFloatTrack& Track = *TrackIt; if(Track.CurveFloat->GetOuter()->IsA(UBlueprint::StaticClass())) { Track.CurveFloat->Rename(*Template->MakeUniqueCurveName(Track.CurveFloat, Track.CurveFloat->GetOuter()), Blueprint, REN_DontCreateRedirectors); } } for( auto TrackIt = Template->EventTracks.CreateIterator(); TrackIt; ++TrackIt ) { FTTEventTrack& Track = *TrackIt; if(Track.CurveKeys->GetOuter()->IsA(UBlueprint::StaticClass())) { Track.CurveKeys->Rename(*Template->MakeUniqueCurveName(Track.CurveKeys, Track.CurveKeys->GetOuter()), Blueprint, REN_DontCreateRedirectors); } } for( auto TrackIt = Template->VectorTracks.CreateIterator(); TrackIt; ++TrackIt ) { FTTVectorTrack& Track = *TrackIt; if(Track.CurveVector->GetOuter()->IsA(UBlueprint::StaticClass())) { Track.CurveVector->Rename(*Template->MakeUniqueCurveName(Track.CurveVector, Track.CurveVector->GetOuter()), Blueprint, REN_DontCreateRedirectors); } } for( auto TrackIt = Template->LinearColorTracks.CreateIterator(); TrackIt; ++TrackIt ) { FTTLinearColorTrack& Track = *TrackIt; if(Track.CurveLinearColor->GetOuter()->IsA(UBlueprint::StaticClass())) { Track.CurveLinearColor->Rename(*Template->MakeUniqueCurveName(Track.CurveLinearColor, Track.CurveLinearColor->GetOuter()), Blueprint, REN_DontCreateRedirectors); } } } FBlueprintEditorUtils::ValidateBlueprintChildVariables(Blueprint, TimelineName); FBlueprintEditorUtils::MarkBlueprintAsStructurallyModified(Blueprint); } }
UBlueprint *UReimportFbxSceneFactory::UpdateOriginalBluePrint(FString &BluePrintFullName, void* VoidNodeStatusMapPtr, TSharedPtr<FFbxSceneInfo> SceneInfoPtr, TSharedPtr<FFbxSceneInfo> SceneInfoOriginalPtr, TArray<FAssetData> &AssetDataToDelete) { if (!SceneInfoPtr.IsValid() || VoidNodeStatusMapPtr == nullptr || !SceneInfoOriginalPtr.IsValid() || BluePrintFullName.IsEmpty()) { return nullptr; } FbxSceneReimportStatusMapPtr NodeStatusMapPtr = (FbxSceneReimportStatusMapPtr)VoidNodeStatusMapPtr; //Find the BluePrint FAssetRegistryModule& AssetRegistryModule = FModuleManager::LoadModuleChecked<FAssetRegistryModule>("AssetRegistry"); FAssetData BlueprintAssetData = AssetRegistryModule.Get().GetAssetByObjectPath(FName(*(BluePrintFullName))); UPackage* PkgExist = LoadPackage(nullptr, *BlueprintAssetData.PackageName.ToString(), LOAD_Verify | LOAD_NoWarn); if (PkgExist == nullptr) { return nullptr; } //Load the package before searching the asset PkgExist->FullyLoad(); UBlueprint* BluePrint = FindObjectSafe<UBlueprint>(ANY_PACKAGE, *BluePrintFullName); if (BluePrint == nullptr) { return nullptr; } //Close all editor that edit this blueprint FAssetEditorManager::Get().CloseAllEditorsForAsset(BluePrint); //Set the import status for the next reimport for (TSharedPtr<FFbxNodeInfo> NodeInfo : SceneInfoPtr->HierarchyInfo) { if (!NodeStatusMapPtr->Contains(NodeInfo->NodeHierarchyPath)) continue; EFbxSceneReimportStatusFlags NodeStatus = *(NodeStatusMapPtr->Find(NodeInfo->NodeHierarchyPath)); NodeInfo->bImportNode = (NodeStatus & EFbxSceneReimportStatusFlags::ReimportAsset) != EFbxSceneReimportStatusFlags::None; } //Add back the component that was in delete state but no flag for reimport for (TSharedPtr<FFbxNodeInfo> OriginalNodeInfo : SceneInfoOriginalPtr->HierarchyInfo) { if (!NodeStatusMapPtr->Contains(OriginalNodeInfo->NodeHierarchyPath)) { continue; } EFbxSceneReimportStatusFlags NodeStatus = *(NodeStatusMapPtr->Find(OriginalNodeInfo->NodeHierarchyPath)); if (OriginalNodeInfo->bImportNode != true || (NodeStatus & EFbxSceneReimportStatusFlags::ReimportAsset) != EFbxSceneReimportStatusFlags::None) { continue; } //Clear the child OriginalNodeInfo->Childrens.Empty(); //hook the node to the new hierarchy parent bool bFoundParent = false; if (OriginalNodeInfo->ParentNodeInfo.IsValid()) { int32 InsertIndex = 0; for (TSharedPtr<FFbxNodeInfo> NodeInfo : SceneInfoPtr->HierarchyInfo) { InsertIndex++; if (NodeInfo->bImportNode && NodeInfo->NodeHierarchyPath.Compare(OriginalNodeInfo->ParentNodeInfo->NodeHierarchyPath) == 0) { OriginalNodeInfo->ParentNodeInfo = NodeInfo; NodeInfo->Childrens.Add(OriginalNodeInfo); SceneInfoPtr->HierarchyInfo.Insert(OriginalNodeInfo, InsertIndex); bFoundParent = true; break; } } } if (!bFoundParent) { //Insert after the root node OriginalNodeInfo->ParentNodeInfo = nullptr; SceneInfoPtr->HierarchyInfo.Insert(OriginalNodeInfo, 1); } } //Create a brand new actor with the correct component hierarchy then replace the existing blueprint //This function is using the bImportNode flag not the EFbxSceneReimportStatusFlags AActor *HierarchyActor = CreateActorComponentsHierarchy(SceneInfoPtr); if (HierarchyActor != nullptr) { //Modify the current blueprint to reflect the new actor //Clear all nodes by removing all root node TArray<USCS_Node*> BluePrintRootNodes = BluePrint->SimpleConstructionScript->GetRootNodes(); for(USCS_Node* RootNode : BluePrintRootNodes) { RemoveChildNodeRecursively(BluePrint->SimpleConstructionScript, RootNode); } //Create the new nodes from the hierarchy actor FKismetEditorUtilities::AddComponentsToBlueprint(BluePrint, HierarchyActor->GetInstanceComponents()); //Cleanup the temporary actor HierarchyActor->Destroy(); BluePrint->Modify(); BluePrint->PostEditChange(); AssetToSyncContentBrowser.Add(BluePrint); return BluePrint; } return nullptr; }