void UK2Node_AddComponent::ValidateNodeDuringCompilation(FCompilerResultsLog& MessageLog) const { Super::ValidateNodeDuringCompilation(MessageLog); UActorComponent* Template = GetTemplateFromNode(); if (Template) { UClass* TemplateClass = Template->GetClass(); if (!TemplateClass->IsChildOf(UActorComponent::StaticClass()) || TemplateClass->HasAnyClassFlags(CLASS_Abstract) || !TemplateClass->HasMetaData(FBlueprintMetadata::MD_BlueprintSpawnableComponent) ) { FFormatNamedArguments Args; Args.Add(TEXT("TemplateClass"), FText::FromString(TemplateClass->GetName())); Args.Add(TEXT("NodeTitle"), GetNodeTitle(ENodeTitleType::FullTitle)); MessageLog.Error(*FText::Format(NSLOCTEXT("KismetCompiler", "InvalidComponentTemplate_Error", "Invalid class '{TemplateClass}' used as template by '{NodeTitle}' for @@"), Args).ToString(), this); } if (UChildActorComponent const* ChildActorComponent = Cast<UChildActorComponent const>(Template)) { UBlueprint const* Blueprint = GetBlueprint(); UClass const* ChildActorClass = ChildActorComponent->GetChildActorClass(); if (ChildActorClass == Blueprint->GeneratedClass) { UEdGraph const* ParentGraph = GetGraph(); UEdGraphSchema_K2 const* K2Schema = GetDefault<UEdGraphSchema_K2>(); if (K2Schema->IsConstructionScript(ParentGraph)) { FFormatNamedArguments Args; Args.Add(TEXT("ChildActorClass"), FText::FromString(ChildActorClass->GetName())); MessageLog.Error(*FText::Format(NSLOCTEXT("KismetCompiler", "AddSelfComponent_Error", "@@ cannot add a '{ChildActorClass}' component in the construction script (could cause infinite recursion)."), Args).ToString(), this); } } else if (ChildActorClass != nullptr) { AActor const* ChildActor = Cast<AActor>(ChildActorClass->ClassDefaultObject); check(ChildActor != nullptr); USceneComponent* RootComponent = ChildActor->GetRootComponent(); if ((RootComponent != nullptr) && (RootComponent->Mobility == EComponentMobility::Static) && (ChildActorComponent->Mobility != EComponentMobility::Static)) { FFormatNamedArguments Args; Args.Add(TEXT("ChildActorClass"), FText::FromString(ChildActorClass->GetName())); MessageLog.Error(*FText::Format(NSLOCTEXT("KismetCompiler", "AddStaticChildActorComponent_Error", "@@ cannot add a '{ChildActorClass}' component as it has static mobility, and the ChildActorComponent does not."), Args).ToString(), this); } } } } else { FFormatNamedArguments Args; Args.Add(TEXT("NodeTitle"), GetNodeTitle(ENodeTitleType::FullTitle)); MessageLog.Error(*FText::Format(NSLOCTEXT("KismetCompiler", "MissingComponentTemplate_Error", "Unknown template referenced by '{NodeTitle}' for @@"), Args).ToString(), this); } }
void UK2Node_AddComponent::AllocatePinsForExposedVariables() { const UEdGraphSchema_K2* K2Schema = GetDefault<UEdGraphSchema_K2>(); const UActorComponent* TemplateComponent = GetTemplateFromNode(); const UClass* ComponentClass = TemplateComponent ? TemplateComponent->GetClass() : nullptr; if (ComponentClass != nullptr) { const UObject* ClassDefaultObject = ComponentClass ? ComponentClass->ClassDefaultObject : nullptr; for (TFieldIterator<UProperty> PropertyIt(ComponentClass, EFieldIteratorFlags::IncludeSuper); PropertyIt; ++PropertyIt) { UProperty* Property = *PropertyIt; const bool bNotDelegate = !Property->IsA(UMulticastDelegateProperty::StaticClass()); const bool bIsExposedToSpawn = UEdGraphSchema_K2::IsPropertyExposedOnSpawn(Property); const bool bIsVisible = Property->HasAllPropertyFlags(CPF_BlueprintVisible); const bool bNotParam = !Property->HasAllPropertyFlags(CPF_Parm); if(bNotDelegate && bIsExposedToSpawn && bIsVisible && bNotParam) { FEdGraphPinType PinType; K2Schema->ConvertPropertyToPinType(Property, /*out*/ PinType); const bool bIsUnique = (NULL == FindPin(Property->GetName())); if (K2Schema->FindSetVariableByNameFunction(PinType) && bIsUnique) { UEdGraphPin* Pin = CreatePin(EGPD_Input, TEXT(""), TEXT(""), NULL, false, false, Property->GetName()); Pin->PinType = PinType; bHasExposedVariable = true; if ((ClassDefaultObject != nullptr) && K2Schema->PinDefaultValueIsEditable(*Pin)) { FString DefaultValueAsString; const bool bDefaultValueSet = FBlueprintEditorUtils::PropertyValueToString(Property, reinterpret_cast<const uint8*>(ClassDefaultObject), DefaultValueAsString); check(bDefaultValueSet); K2Schema->TrySetDefaultValue(*Pin, DefaultValueAsString); } // Copy tooltip from the property. K2Schema->ConstructBasicPinTooltip(*Pin, Property->GetToolTipText(), Pin->PinToolTip); } } } } // Hide transform and attachment pins if it is not a scene component const bool bHideTransformPins = (ComponentClass != nullptr) ? !ComponentClass->IsChildOf(USceneComponent::StaticClass()) : false; UEdGraphPin* ManualAttachmentPin = GetManualAttachmentPin(); ManualAttachmentPin->SafeSetHidden(bHideTransformPins); UEdGraphPin* TransformPin = GetRelativeTransformPin(); TransformPin->SafeSetHidden(bHideTransformPins); }
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(); }
const UClass* UK2Node_AddComponent::GetSpawnedType() const { const UActorComponent* TemplateComponent = GetTemplateFromNode(); return TemplateComponent ? TemplateComponent->GetClass() : NULL; }