OnConstruction and BP construction script order

I have a C++ pawn subclass with OnConstruction overidden:

void AMyPawn::OnConstruction(const FTransform& transform)
{
    UE_LOG(LogTemp, Warning, TEXT("OnConstruction"))
    Super::OnConstruction(transform);
}

In the Editor, I’ve created a Blueprint from AMyPawn, and created the following Construction script:

278860-bp-construction.png

When the construction scripts run however, this is what I see in the log:

278861-construction.png

These messages seem out of order. I would expect my parent class’s OnConstruction method to behave like a C++ constructor and run before the subclassed construction script, or at least when I explicitly call Super::OnConstruction. But this doesn’t seem to be the case.

The underlying problem that led to this is that I’m creating a procedural mesh in C++ OnConstruction, but I’m setting its material in the BP subclass. I can’t do this however because my OnConstruction uses UKismetProceduralMeshLibrary::CopyProceduralMeshFromStaticMeshComponent, and that blows away any material data set by the BP construction script.

Is it incorrect to use both a BP and a C++ construction script? Is there a better way to approach this?

1 Like

I came to the same observation, and it is a pity there is no information about this.

In my situation I have a function in a BP construction script which takes in a vector as input paramter, and this vector I set from OnConstruction(). I would have expected that OnConstruction() runs earlier then the BP construction script.

However, unfortuantely the BP construction script function executes before (about 14 ms earlier) than the C++ code and the function does not work properly.

They are two dfiferent functions.

BP Construction script is declared as UserConstructionScript which is a BlueprintImplementableEvent so it cannot be overriden in C++.

OnConstruction is a separate virtual native method with no base implementation
image
(so calling Super::OnConstruction is kinda useless)

OnConstruction is always executed after UserConstructionScript.

However what you can do is, declare a new “PostConstruction” blueprint overridable, and trigger it from your OnConstruction override.

//.h
virtual void OnConstruction() override;

UFUNCTION(BlueprintImplementableEvent)
void PostConstruction();

//.cpp
void AMyActor::OnConstruction()
{
    Super::OnConstruction();

    //...

    PostConstruction();
}

Alternatively, maybe you can use an earlier method in the C++ construction steps, if you just need to change things before BP construction script :

2 Likes

Found a similar response when digging some more. I got this reply on UDN from Jon Lambert from Epic Games (maybe you find it useful):

"
AActor::UserConstructionScript is the BlueprintImplementable event that is called the “Construction Script” in the Blueprint Editor. It’s a common misconception, but the OnConstruction function is not really meant to be the native equivalent of the UserConstructionScript, a.k.a. Blueprint Construction Script. OnConstruct is called after the Blueprint’s components have been created and registered, so it shouldn’t be used to inform the UserConstructionScript, but it’s good for setting values or running some post construction setup. The reason it works in the level editor, but not in a spawned actor is because OnConstruct get’s a chance to run before subsequent reruns of the UserConstructionScript that occur while you are editing the instance. When spawning the actor, ExecuteConstruction is only run once, so the property isn’t set in time for your construction script. In your case, it sounds like you could move the logic out of OnConstruct and into a Blueprint Callable function and call that from your BP’s construction script.
"