void ReattachComponents(const TArray<FString>& Args) { if(Args.Num() != 1) { UE_LOG(LogConsoleResponse, Warning, TEXT("Reattach.Components: missing class name parameter")); return; } UE_LOG(LogConsoleResponse, Display, TEXT("Reattach.Components:")); UClass* Class=NULL; if( ParseObject<UClass>( *Args[0], TEXT("CLASS="), Class, ANY_PACKAGE ) && Class->IsChildOf(UActorComponent::StaticClass()) ) { for( FObjectIterator It(Class); It; ++It ) { UActorComponent* ActorComponent = Cast<UActorComponent>(*It); if( ActorComponent ) { UE_LOG(LogConsoleResponse, Display, TEXT(" Component: %s"), *ActorComponent->GetName()); FComponentReregisterContext Reregister(ActorComponent); } } UE_LOG(LogConsoleResponse, Display, TEXT("")); } else { UE_LOG(LogConsoleResponse, Warning, TEXT("Reattach.Components: No objects with the class name '%s' found"), *Args[0]); } }
void SGraphPinLiveEditVar::GenerateComboBoxIndexes( TArray< TSharedPtr<int32> >& OutComboBoxIndexes ) { if ( !NodeClass.IsValid() ) return; UClass *InClass = Cast<UClass>(NodeClass.Get()); if ( InClass == NULL ) return; GenerateComboBoxIndexesRecurse( InClass, FString(TEXT("")), OutComboBoxIndexes ); AActor *AsActor = Cast<AActor>(InClass->ClassDefaultObject); if ( AsActor != NULL ) { TArray<UActorComponent*> ActorComponents; AsActor->GetComponents(ActorComponents); for ( TArray<UActorComponent*>::TIterator ComponentIt(ActorComponents); ComponentIt; ++ComponentIt ) { UActorComponent *Component = *ComponentIt; check( Component != NULL ); FString ComponentName = Component->GetName() + FString(TEXT(".")); GenerateComboBoxIndexesRecurse( Component->GetClass(), ComponentName, OutComboBoxIndexes ); } } for (int32 i = 0; i < VariableNameList.Num(); ++i) { TSharedPtr<int32> EnumIdxPtr(new int32(i)); OutComboBoxIndexes.Add(EnumIdxPtr); } }
//------------------------------------------------------------------------------ // Evolved from a combination of FK2ActionMenuBuilder::CreateAddComponentAction() // and FEdGraphSchemaAction_K2AddComponent::PerformAction(). UEdGraphNode* UBlueprintComponentNodeSpawner::Invoke(UEdGraph* ParentGraph, FBindingSet const& Bindings, FVector2D const Location) const { check(ComponentClass != nullptr); auto PostSpawnLambda = [](UEdGraphNode* NewNode, bool bIsTemplateNode, FCustomizeNodeDelegate UserDelegate) { UK2Node_AddComponent* AddCompNode = CastChecked<UK2Node_AddComponent>(NewNode); UBlueprint* Blueprint = AddCompNode->GetBlueprint(); UFunction* AddComponentFunc = FindFieldChecked<UFunction>(AActor::StaticClass(), UK2Node_AddComponent::GetAddComponentFunctionName()); AddCompNode->FunctionReference.SetFromField<UFunction>(AddComponentFunc, FBlueprintEditorUtils::IsActorBased(Blueprint)); UserDelegate.ExecuteIfBound(NewNode, bIsTemplateNode); }; FCustomizeNodeDelegate PostSpawnDelegate = FCustomizeNodeDelegate::CreateStatic(PostSpawnLambda, CustomizeNodeDelegate); // let SpawnNode() allocate default pins (so we can modify them) UK2Node_AddComponent* NewNode = Super::SpawnNode<UK2Node_AddComponent>(NodeClass, ParentGraph, FBindingSet(), Location, PostSpawnDelegate); // set the return type to be the type of the template UEdGraphPin* ReturnPin = NewNode->GetReturnValuePin(); if (ReturnPin != nullptr) { ReturnPin->PinType.PinSubCategoryObject = *ComponentClass; } bool const bIsTemplateNode = FBlueprintNodeTemplateCache::IsTemplateOuter(ParentGraph); if (!bIsTemplateNode) { UBlueprint* Blueprint = NewNode->GetBlueprint(); UActorComponent* ComponentTemplate = ConstructObject<UActorComponent>(ComponentClass, Blueprint->GeneratedClass); ComponentTemplate->SetFlags(RF_ArchetypeObject); Blueprint->ComponentTemplates.Add(ComponentTemplate); // set the name of the template as the default for the TemplateName param UEdGraphPin* TemplateNamePin = NewNode->GetTemplateNamePinChecked(); if (TemplateNamePin != nullptr) { TemplateNamePin->DefaultValue = ComponentTemplate->GetName(); } } // apply bindings, after we've setup the template pin ApplyBindings(NewNode, Bindings); return NewNode; }
UEdGraphNode* FEdGraphSchemaAction_K2AddComponent::PerformAction(class UEdGraph* ParentGraph, UEdGraphPin* FromPin, const FVector2D Location, bool bSelectNewNode/* = true*/) { if (ComponentClass == NULL) { return NULL; } UBlueprint* Blueprint = FBlueprintEditorUtils::FindBlueprintForGraphChecked(ParentGraph); UEdGraphNode* NewNode = FEdGraphSchemaAction_K2NewNode::PerformAction(ParentGraph, FromPin, Location, bSelectNewNode); if ((NewNode != NULL) && (Blueprint != NULL)) { UK2Node_AddComponent* AddCompNode = CastChecked<UK2Node_AddComponent>(NewNode); ensure(NULL != Cast<UBlueprintGeneratedClass>(Blueprint->GeneratedClass)); // Then create a new template object, and add to array in UActorComponent* NewTemplate = NewObject<UActorComponent>(Blueprint->GeneratedClass, ComponentClass, NAME_None, RF_ArchetypeObject | RF_Public); Blueprint->ComponentTemplates.Add(NewTemplate); // Set the name of the template as the default for the TemplateName param UEdGraphPin* TemplateNamePin = AddCompNode->GetTemplateNamePinChecked(); if (TemplateNamePin) { TemplateNamePin->DefaultValue = NewTemplate->GetName(); } // Set the return type to be the type of the template UEdGraphPin* ReturnPin = AddCompNode->GetReturnValuePin(); if (ReturnPin) { ReturnPin->PinType.PinSubCategoryObject = *ComponentClass; } // Set the asset if(ComponentAsset != NULL) { FComponentAssetBrokerage::AssignAssetToComponent(NewTemplate, ComponentAsset); } AddCompNode->ReconstructNode(); } FBlueprintEditorUtils::MarkBlueprintAsModified(Blueprint); return NewNode; }
void UK2Node_AddComponent::PostPasteNode() { Super::PostPasteNode(); // There is a template associated with this node that should be unique, but after a node is pasted, it either points to a // template shared by the copied node, or to nothing (when pasting into a different blueprint) const UEdGraphSchema_K2* K2Schema = GetDefault<UEdGraphSchema_K2>(); UBlueprint* Blueprint = GetBlueprint(); // Find the template name and return type pins UEdGraphPin* TemplateNamePin = GetTemplateNamePin(); UEdGraphPin* ReturnPin = GetReturnValuePin(); if ((TemplateNamePin != NULL) && (ReturnPin != NULL)) { // Find the current template if it exists FString TemplateName = TemplateNamePin->DefaultValue; UActorComponent* SourceTemplate = Blueprint->FindTemplateByName(FName(*TemplateName)); // Determine the type of the component needed UClass* ComponentClass = Cast<UClass>(ReturnPin->PinType.PinSubCategoryObject.Get()); if (ComponentClass) { ensure(NULL != Cast<UBlueprintGeneratedClass>(Blueprint->GeneratedClass)); // Create a new template object and update the template pin to point to it UActorComponent* NewTemplate = NewObject<UActorComponent>(Blueprint->GeneratedClass, ComponentClass, NAME_None, RF_ArchetypeObject|RF_Public); Blueprint->ComponentTemplates.Add(NewTemplate); TemplateNamePin->DefaultValue = NewTemplate->GetName(); // Copy the old template data over to the new template if it's compatible if ((SourceTemplate != NULL) && (SourceTemplate->GetClass()->IsChildOf(ComponentClass))) { TArray<uint8> SavedProperties; FObjectWriter Writer(SourceTemplate, SavedProperties); FObjectReader(NewTemplate, SavedProperties); } else if(TemplateBlueprint.Len() > 0) { // try to find/load our blueprint to copy the template UBlueprint* SourceBlueprint = FindObject<UBlueprint>(NULL, *TemplateBlueprint); if(SourceBlueprint != NULL) { SourceTemplate = SourceBlueprint->FindTemplateByName(FName(*TemplateName)); if ((SourceTemplate != NULL) && (SourceTemplate->GetClass()->IsChildOf(ComponentClass))) { TArray<uint8> SavedProperties; FObjectWriter Writer(SourceTemplate, SavedProperties); FObjectReader(NewTemplate, SavedProperties); } } TemplateBlueprint.Empty(); } } else { // Clear the template connection; can't resolve the type of the component to create ensure(false); TemplateNamePin->DefaultValue = TEXT(""); } } }
bool UBlueprint::ChangeOwnerOfTemplates() { UBlueprintGeneratedClass* BPGClass = Cast<UBlueprintGeneratedClass>(*GeneratedClass); bool bIsStillStale = false; if (BPGClass) { check(!bIsRegeneratingOnLoad); // >>> Backwards Compatibility: VER_UE4_EDITORONLY_BLUEPRINTS bool bMigratedOwner = false; for( auto CompIt = ComponentTemplates.CreateIterator(); CompIt; ++CompIt ) { UActorComponent* Component = (*CompIt); check(Component); if(Component->GetOuter() == this) { const bool bRenamed = Component->Rename(*Component->GetName(), BPGClass, REN_ForceNoResetLoaders|REN_DoNotDirty); ensure(bRenamed); bIsStillStale |= !bRenamed; bMigratedOwner = true; } } for( auto CompIt = Timelines.CreateIterator(); CompIt; ++CompIt ) { UTimelineTemplate* Template = (*CompIt); check(Template); if(Template->GetOuter() == this) { const FString OldTemplateName = Template->GetName(); ensure(!OldTemplateName.EndsWith(TEXT("_Template"))); const bool bRenamed = Template->Rename(*UTimelineTemplate::TimelineVariableNameToTemplateName(Template->GetFName()), BPGClass, REN_ForceNoResetLoaders|REN_DoNotDirty); ensure(bRenamed); bIsStillStale |= !bRenamed; ensure(OldTemplateName == UTimelineTemplate::TimelineTemplateNameToVariableName(Template->GetFName())); bMigratedOwner = true; } } if(USimpleConstructionScript* SCS = SimpleConstructionScript) { if(SCS->GetOuter() == this) { const bool bRenamed = SCS->Rename(NULL, BPGClass, REN_ForceNoResetLoaders|REN_DoNotDirty); ensure(bRenamed); bIsStillStale |= !bRenamed; bMigratedOwner = true; } } if (bMigratedOwner) { BPGClass->ComponentTemplates = ComponentTemplates; BPGClass->Timelines = Timelines; BPGClass->SimpleConstructionScript = SimpleConstructionScript; } // <<< End Backwards Compatibility } else { UE_LOG(LogBlueprint, Log, TEXT("ChangeOwnerOfTemplates: No BlueprintGeneratedClass in %s"), *GetName()); } return !bIsStillStale; }