Physics when TickPhysicsAsync is enabled is not accurate.

I am currently planning to implement car suspension on Unreal Engine 5.1. I tried to use substepping to avoid causing physics to explode, but unlike UE4, FCalculatePhysics doesn’t seem to work anymore. So I looked it up more and found out that AsyncPhysicsTickActor handles it(It is called whenever substepping or asyn physics is executed). However, unlike UE4, which worked well when I applied force to the body instance, AsyncPhysicsTickActor seemed to no longer consider delta time. So I wrote the code just like the way Chaos Vehicle used.
The problem starts here. When I apply a huge force forward to make the car move really fast, there’s no problem substepping is turned on, but if I turn on the TickPhysicsAsync, the car leans forward enough for the bumper to touch the ground. Delta time is not an issue because the time step is set to 1/120. I verified delta time is 1/120.
This is the code(I saw in Chaos Vehicle) that implements the suspension force, and there is no physical interaction other than this. This code is invoked at the end of the AsyncPhysicsTickActor.

Chaos::FRigidBodyHandle_Internal* Handle = Parent->BodyInstance.ActorHandle->GetPhysicsThreadAPI();
FVector COM = Chaos::FParticleUtilitiesGT::GetCoMWorldPosition(Handle);
FVector Torque = Chaos::FVec3::CrossProduct(TraceResult.ImpactPoint - COM, NormalForce);
Handle->AddForce(NormalForce, false);
Handle->AddTorque(Torque, false);

In fact, not only this, but unlike UE4, UE5 seems to lack a lot of physics-related information. No matter how much I search the Internet and source code, it’s not easy to get physics-related information. It’s even worse when it comes to substepping.

2 Likes

I found a solution myself. GetComponentLocation should not be used when the location of the component is required. This does not bring the position of the substep, but simply brings the position of the tick, resulting in an error. Instead, you need to get the position directly from the rigid body. This ensures stable operation even if the graphic fps is 1.

Chaos::FRigidBodyHandle_Internal* RigidBody = Parent->BodyInstance.ActorHandle->GetPhysicsThreadAPI();
FTransform ParentTransform = FTransform(RigidBody->R(), RigidBody->X());
FVector ComponentLocation = ParentTransform.TransformPosition(GetRelativeLocation());
FRotator ComponentRotation = ParentTransform.TransformRotation(GetRelativeRotation().Quaternion()).Rotator();

Component Location and Component Rotation are now the true position and rotation.

3 Likes