Physical Animation Component is the out-of-the-box solution for motorised ragdolls, we use it to produce a smoother transition into full ragdoll by manipulating the motor strength.
You can reproduce the bug with the dummy character in the physics viewer which also has physical animation component…what’s strange is that even with no active physical animation profile selected (motor strength of 0) i am still seeing the jittering, which would indicate that kinematic targets are still constantly moving (albeit by a vary minor amount).
Aha! Okay I’d need to see a repro, but this could be that the PhysicalAnimationComponent is applying forces on top of the ragdoll simulation, adding another level of things fighting for convergence. This could lead to what you are seeing. Why is this enabled when the character is ragdolling though?
I see, can you send this as a repro exactly how you have it set up.
I can completely see the use case for this, but when the full ragdoll is blended in - for me this shouldn’t have any constraints from this component. I’d like to see if they are finding their way to the solver.
Frustratingly I tried following the same set up in vanilla engine but I am not able to observe the same jitteriness we see in our own project. I also don’t have the source downloaded so I can’t really confirm if the island has actually gone to sleep in the debugger.
In any case I have zipped up a new version of the test project, once you load up the level press the P key to start ragdoll.
Here’s a summery of the setup:
In the physics asset (PA_Mannequin) I’ve added a new physical animation profile called ‘Test’
The player character now has a Physical Animation Component
The Physical Animation Component is linked to the Skeletal Mesh Component on the begin play event.
When the ‘P’ Key is pressed:
Enable simulation for all bodies below pelvis
Set blend weight for all bodies below pelvis to 1.0
Activate the ‘Test’ profile on the physical animation component.
Set the strength to 0 so it should have no effect.
Thank you for the repro - that helps a lot. I’ve had both Jittery cases and settled cases in the example… but even stationary and what looks to be settled it isn’t sleeping. As a quick helper - we have an awesome tool called Chaos Visual Debugger which you can use to check most physics things. Chaos Visual Debugger - User Guide for UE 5.4 | Tutorial
I’m going to check what is happening at the core level and see why the kinematic side isn’t converging
I’ve taken a look into this, and the issue in this case is the interaction from the Physical Animation Component, and the Physics Engine was at fault. Essentially the Kinematic Target type is reset each tick, and it is designed to go through a multi tick stage process which isn’t happening. The simplest, and likely default way of using this is to add an extra node to your blueprint to set the SkeletalMesh to a nullptr as in the picture attached. This then stops the per tick update from the PAC and the character will then go to sleep.
[Image Removed]If you can try this and confirm it works on your end that’d be much appreciated.
Hi Geoff, I can confirm that clearing out unlinking the skeletal mesh from the physical animation component does fix the issue and the physics bodies are going to sleep as expected, I think as a stopgap fix this will be good for now, thanks for all the help!
I’ll reach out to the devs and find out if this is expected - I’ve seen this used for example to move a character in a vehicle sim, so it may not be designed to switch off unless this is reset by the method above - it could be a good old fashioned bug
Can you clarify on how USkeletalMeshComponent::IsAnyRigidBodyAwake() can help me? As far as I can tell the rigid bodies never got put to sleep because Chaos disables the code path for rigid bodies on the ragdoll (i.e. they are constrained). The only way I can think of is by externally monitoring the linear speeds of the bodies and then manually put the bodies to sleep, effectively doing the work ProcessParticlesSleep() is already doing.
Is it possible to put in a support ticket request for this? As ragdoll physics isn’t really usable feature out of the box if it’s struggling to come to a settle.
I traced the code a bit and I think I’ve found the issue.
In
void FPBDIslandManager::ProcessSleep(const FRealSingle Dt)It will only process island sleep if Island->Flags.bIsSleepAllowed is set to true, which it does every frame with this comment:
// This gets set to false again next tick if there are moving kinematics in the island Island->Flags.bIsSleepAllowed = true;Next in here:
void FPBDIslandManager::UpdateGraphNode(FPBDIslandParticle* Node)It looks like it will not allow the island to sleep if the particle is moving. This is the test to determine if the particle is moving:
bool IsParticleMoving(const FGeometryParticleHandle* Particle)It looks like there are a few kinematic spheres in position mode (I don’t know what they are to be honest, as they are not associated with any bone and the debug names are empty)
And to check if the sphere is moving it checks if the delta between the target and the particle position is non-zero:
// For kinematic particles check whether their current mode and target will cause the particle to move // For all other modes (Velocity, None and Reset) check that the velocity is non-zero const FKinematicGeometryParticleHandle* Kinematic = Particle->CastToKinematicParticle(); const FKinematicTarget& KinematicTarget = Kinematic->KinematicTarget(); if (KinematicTarget.GetMode() == EKinematicTargetMode::Position) { bIsStationary = (Kinematic->GetX() - KinematicTarget.GetPosition()).IsZero() && (Kinematic->GetRf() * KinematicTarget.GetRotation().Inverse()).IsIdentity(); } else { bIsStationary = Kinematic->GetV().IsZero() && Kinematic->GetW().IsZero(); }These spheres then prevent the entire island to go to sleep. I double checked the actual delta and it looks very small. Perhaps we just need some sort of threshold here?