Download

Replace a C++ Native Component with a Derived class

Hey, I’m trying to figure out how on earth to solve this gracefully -

I need to replace a Native Component with a Blueprint derived class.

Lets say we have:

UCLASS()
class Foo  : public AActor {
    ...

    UPROPERTY(EditAnywhere)
    UBarComponent* ReplaceableComponent;
    ...
    public Foo() {
        ReplaceableComponent= CreateDefaultSubobject< UBarComponent>( TEXT( "ReplaceableComponent" ) );
    }
}

Now, if I blueprint my class Foo, in the left hand pane, I can see my Native Component registered.
But I want to replace this instance, for this blueprint only.

Say I have created another Blueprint based off of UBarComponent called BP_MyBarComponent.
The blueprint editor will not let me replace “ReplaceableComponent” with an instance of BP_MyBarComponent.

Has anyone figured out how to deal with this?

You can’t replace them with Blueprint classes. The best you can do for that is expose a variable which you set in your Blueprint construction script or similar.

This seems to me like an oversight, the C++ class is blueprinted into a blueprint class, just like how we can override the CDO’s CreateDefaultSubobject in C++, we should be able to override the Default Subobjects in Blueprint… After all, that blueprint class has to be read from disk anyways…

I guess this could be done via the ConstructionScript in blueprint if the UPROPERTY() has BlueprintReadWrite on it.

I agree; it seems like it should be possible to override which class is used in a CreateDefaultSubobject<> instantiation. All the data necessary should be there for the engine to do the right thing.

It’s been asked for for a long time, but still isn’t supported. The only way to do this IMO, would be to inject into the “Simple Construction Script” that Blueprint uses to create components, and have a pop-up that lets you choose a derived component from the creation dialog box.

There is no CDO for Blueprints, and the C++ Constructor runs a long time before any Blueprint serialization, so no doubt it becomes a bit of a minefield, which is probably why they haven’t done it. For now, I’ve found the simplest method is to just set a Read/Write variable or call a Setter function that throws an error if called outside of the construction script.

this caught my eye. is there some method internally of doing this, or are you just setting a bool to flag it?

You can use the existing bActorIsBeingConstructed to guard against it.

1 Like

From what I understand the construction script is called when the blueprint is moved/updated as well though no? Wouldn’t this cause all the manually set data overrides to be cleared constantly?

Only when you move or update it in the editor, and if you’re only setting a value it shouldn’t be a problem.