Add Offset/Rotation or Set Location/Rotation doesn't work just after turning on Simulate Physics!

Hey, I have a Skeletal Mesh Component as the Root Component with physics disabled.
But when I enable it after a certain event, physics works just fine. But the rotation doesn’t updates. But the AddWorldRotation is getting called cause if I remove the TeleportType flag, then editor gives me warning. Its a one time function btw!
Here is the code that does work! It works when I add rotation before adding rotation

void AWeapon::ThrowWeapon()
{
	GetItemMesh()->AddLocalRotation(FRotator(0, 90, 0), false, nullptr, ETeleportType::TeleportPhysics);
	GetItemMesh()->SetSimulatePhysics(true);
	FVector ImpulseDirection = GetActorForwardVector();
	float RandomRotationZ{ FMath::RandRange(-45.f, 45.f) };
	ImpulseDirection = ImpulseDirection.RotateAngleAxis(RandomRotationZ, FVector(0, 0, 1));
	GetItemMesh()->AddImpulse(4'000 * ImpulseDirection);
}

Whereas the code below doesn’t works. Everything works same as above except rotation. Mesh doesn’t rotates even a single degree.


void AWeapon::ThrowWeapon()
{
	GetItemMesh()->SetSimulatePhysics(true);
	GetItemMesh()->AddLocalRotation(FRotator(0, 90, 0), false, nullptr, ETeleportType::TeleportPhysics);
	FVector ImpulseDirection = GetActorForwardVector();
	float RandomRotationZ{ FMath::RandRange(-45.f, 45.f) };
	ImpulseDirection = ImpulseDirection.RotateAngleAxis(RandomRotationZ, FVector(0, 0, 1));
	GetItemMesh()->AddImpulse(4'000 * ImpulseDirection);

Can someone help me please?
But if I set a Timer for the same line of code of adding rotation after setting Simulate Physics to on even of 0.0001 second (that is it will be called in the same frame), then it works again.

I mean this >>>

void AWeapon::RotateMesh()
{
	GetItemMesh()->AddLocalRotation(FRotator(0, 90, 0), false, nullptr, ETeleportType::TeleportPhysics);
}
void AWeapon::ThrowWeapon()
{
	GetItemMesh() ->SetSimulatePhysics(true);
	FTimerHandle Handle;
	GetWorldTimerManager().SetTimer(Handle, this, &AWeapon::RotateMesh, 0.0001f);
	FVector ImpulseDirection = GetActorForwardVector();
	float RandomRotationZ{ FMath::RandRange(-45.f, 45.f) };
	ImpulseDirection = ImpulseDirection.RotateAngleAxis(RandomRotationZ, FVector(0, 0, 1));
	GetItemMesh()->AddImpulse(4'000 * ImpulseDirection);
}

I don’t understand this behaviour and I’m stuck. Any help would greatly be appreciated.
And yes Add/Set Location/Rotation all work for Simulated Skeletal Mesh in BeginPlay/Tick.
Thanks,
Dean

Ok so I found what was causing this issue!
Looks like if I set collision enabled to QueryAndPhysics then everything works perfect even with timers.
But if I just set CollisionEnabled to PhysicsOnly and tried to rotate after that line (of course after setting simulate physics to on) then It skips that rotation. Probably due to internal engine and physics processing I think.
Cause Physics system uses location and rotation of that frame to calculate what will be the position and rotation the next frame according to applied velocity and force vectors, It didn’t take that rotation line into account although it was called. But when that line was called, It was not a physics body, it was only a kinematic body(Movable, that’s it). Physics system(PhysX in this case) was still using that previous location and rotation to calculate what would be desired ones next frame. So after applying the rotation in next line, maybe Physics System finally successfully created physics state/body for mesh and passed its details(transform specifically) to the engine so that engine could render it accordingly.
But once Physics State is created, then your all Set/Add Rotation/Location are flushed into physics system so that it can apply those changes after completing a simulation step.
It delays only in PhysicsOnly case and that also in “special” timer case, and that also at that instant after Setting CollisionEnabled to PhysicsOnly, and that also (XD haha) in UE 4.27.2
So if your mesh isn’t rotating and you want to rotate exactly when Physics body starts simulation(that’s probably this case), then you can rotate it before toggling SetSimulatePhysics on.
BTW engine literally takes a few milliseconds to completely make a body simulate physics. But in this case the rotation line was called even before that few milliseconds that’s why it wasn’t flushed to physics system because mesh wasn’t a physics body yet.
But I think UE 5.x would have solved this issue anyways.
Cheers,
Dean

1 Like