Dynamically created component not visible/editable in components window

Hi All,

I am trying to dynamically create and attach a component to my custom component. The issue is the component created does not show in editor, specifically the component window.

As shown in this image, a box collision component is created and attached to UPrimitiveEffectComponent(a custom component I created), but it is not visible in component window.

This image shows NewBlueprint added to the world and the component is selectable but not editable.

The box collision is created when I select BoxCollision as value for CollisionClass.

UPROPERTY( EditAnywhere, Category = "FX|Primitive Effect" )
	TSubclassOf<UShapeComponent> CollisionClass;

I override PostLoad in UPrimitiveEffectComponent to spawn a UShapeComponent if CollisionClass is valid as follows

void UPrimitiveEffectComponent::PostLoad()
{
	Super::PostLoad();
	shapeComponent = NewObject<UShapeComponent>( this, *CollisionClass );
	if ( !ensureAlwaysMsgf( nullptr != shapeComponent, TEXT( "Error creating shape component" ) ) )
		return;

	shapeComponent->AttachToComponent( this, AttachmentRules );
}

What else do I have to do to make the dynamically created and attached box collision show up in editor for editing?

Edit(s)

  1. Added captions for attached images.
2 Likes

Hello! Have you find this solution, I’m in the same issue :frowning:

Set the BlueprintReadWrite in UPROPERTY after the EditAnywhere

1 Like

Me too any solution about this?

The following method works for me when attaching components to actors dynamically in the editor (tested on 4.25.4). However to actually see the component section updated with the new components you need to refresh the Details panel (exempli gratia by selecting another actor on the map and then selecting again the modified actor).

auto const comp = NewObject<UMyComponent>(this, FName{TEXT("MyComponent")});
if (!comp ) { UE_LOG(LogTemp, Error, TEXT("Error creating component")); }

// Magic line. Needed in order to show the component on Component section of Details in the editor
comp->CreationMethod = EComponentCreationMethod::Instance;	

if (!comp->AttachToComponent(parent, FAttachmentTransformRules::SnapToTargetIncludingScale, TEXT("MySocket")))
{
    UE_LOG(LogTemp, Error, TEXT("Impossible to attach the component to the parent"));
}
	
comp->RegisterComponent();

I extrapolated this solution from the last two answers here: https://forums.unrealengine.com/development-discussion/c-gameplay-programming/83390-making-attached-component-editable/page2?111270-Making-attached-component-editable=

2 Likes

This is the code I use to add a dynamic component. Thanks to Tarquiscani0 for leading me to a full answer.

UMyComponent* MyNewComponent= NewObject<UMyComponent>(OwningActor);
MyNewComponent->SetupAttachment(ComponentToAttachTo);
OwningActor->AddInstanceComponent(MyNewComponent);
Owner->AddOwnedComponent(MyNewComponent);
MyNewComponent->RegisterComponent();

AddInstanceComponent() will set the CreationMethod to EComponentCreationMethod::Instance for you :slight_smile:

As previously noted, this will not update the SCSEditor embedded in the details panel.
To avoid having to manually click out and back in, use the following Editor only code to trigger a refresh in PostEditChangeProperty() on your component.

#include "MyComponent.h"

#if WITH_EDITOR
#include "UnrealEdGlobals.h"
#include "Editor/UnrealEdEngine.h"
#endif

...

#if WITH_EDITOR
void UMyComponent::PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent){
     //call Super first! Updates parent-child relationships
    Super::PostEditChangeProperty(PropertyChangedEvent); 
    GUnrealEd->UpdateFloatingPropertyWindows();
}
#endif

Since this introduces a dependency on GEditor you should add the following snippet in your .build.cs for the module to include UnrealEd in editor builds.

if (Target.bBuildEditor == true)
{
	PublicDependencyModuleNames.AddRange(new string[]
	{
		"UnrealEd"
	});
}
5 Likes

I built a whole hierarchy of classes and editor tools for level creation and spent dozens of hours over a better part of a week testing it to track down a little bug that drove me insane.

THIS! This little beauty of a line fixed it all!

Man… I love you.

5 Likes