Difference between spawn from code and place actor manually, mass update issue

Hi, I have an issue with specify actor component’s masses - I see a difference between placing actor directly on level and if I spawn it from another actor. For comparison I’ve setup this actor:

in .h:

UPROPERTY(BlueprintReadWrite, EditAnywhere) UBoxComponent* MainBody; UPROPERTY(BlueprintReadWrite, EditAnywhere) UStaticMeshComponent* MainBodyMesh;

in .cpp:



ATestMultibody::ATestMultibody()
{
	PrimaryActorTick.bCanEverTick = true;

	MainBody = CreateDefaultSubobject<UBoxComponent>("Body");
	SetRootComponent(MainBody);

	MainBody->SetMobility(EComponentMobility::Movable);
	MainBody->SetSimulatePhysics(true);
	MainBody->SetNotifyRigidBodyCollision(true);

	MainBody->SetCollisionEnabled(ECollisionEnabled::QueryAndPhysics);
	MainBody->SetCollisionProfileName(TEXT("BlockAllDynamic"));

	MainBodyMesh = CreateDefaultSubobject<UStaticMeshComponent>("MainBodyMesh");
	MainBodyMesh->SetupAttachment(MainBody);
}

void ATestMultibody::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);
	MainBody->AddForce(F2Ue * FVector(0, 0, 9.80 * 777));
}

void ATestMultibody::OnConstruction(const FTransform& Transform)
{
	MainBodyMesh->GetBodyInstance()->SetMassOverride(777, true);
	MainBodyMesh->GetBodyInstance()->UpdateMassProperties();
	MainBody->GetBodyInstance()->SetMassOverride(0.001, true);
	MainBody->GetBodyInstance()->UpdateMassProperties();
}

So basically I just want to have this actor with desired mass and simulate physics, to make sure that mass updated correctly I apply -g vector to the body - if it’s hovering, that means that everything is ok

When I place the actor manually in the world, it’s hovering
When I place the actor using the following command

ATestMultibody* TestActor = GetWorld()->SpawnActor<ATestMultibody>(TestMultibodyBP, FVector(30, 0, 15) * 100, FRotator());

it doesn’t update the mass and it’s equal to some precalculated values from physic engine

What wrong with that? Those mass overrides are really barely works in a stable robust way, and there is also some issue with order of constructor script work. If I add a logging to Constructor and OnConstructor, I see the following:

If placed manually:

LogTemp: Warning: ATestMultibody::ATestMultibody() is done
LogTemp: Warning: ATestMultibody::OnConstruction() is done
LogTemp: Warning: ATestMultibody::OnConstruction() is done
LogTemp: Warning: ATestMultibody::OnConstruction() is done
LogTemp: Warning: ATestMultibody::ATestMultibody() is done
LogTemp: Warning: ATestMultibody::OnConstruction() is done
LogTemp: Warning: ATestMultibody::OnConstruction() is done
LogTemp: Warning: ATestMultibody::OnConstruction() is done
LogTemp: Warning: ATestMultibody::ATestMultibody() is done

If placed from other actor:

LogTemp: Warning: ATestMultibody::ATestMultibody() is done
LogTemp: Warning: ATestMultibody::ATestMultibody() is done
LogTemp: Warning: ATestMultibody::OnConstruction() is done

I don’t know how can I overcome that in a good way. I don’t want to manually specify masses in blueprints…

Still fighting the problem, and more and more strange things are happening.

I tried to do those override commands in InitializeComponents() and PostInitializeComponents(), also tried to do that after spawn and in BeginPlay(), but it gives very strange behavior - at first run of the in editor game after full rebuild, I see updated value of mass, but the actor goes to heaven. At the second run - no updates in mass, default one is setup and no update at all.