Hello,
When testing against our samples in house, the issue had to do with blend times not being set properly upon setting the character to ragdoll. Basically, if you’re playing a montage and try to blend out what can happen is that even after you put your pawn into ragdoll the blend will still try to force it back to whatever pose you’re blending too.
However, since your simulating now, it doesn’t just cause the position to be reset but also adds forces. Therefore you need to have BlendPhysics enabled before the blending actually starts.
The reason this is potentially more noticeable with time dilation is that the forces applied may get scaled due to that dilation and have more drastic effects.
So, this is really more of a content bug that takes some tweaking to get around.
In our sample Shooter Game, these were the following changes that were made:
void AShooterCharacter::OnDeath(...)
{
// Other code
// Death anim
float DeathAnimDuration = PlayAnimMontage(DeathAnim);
// Ragdoll
if (DeathAnimDuration > 0.f)
{
// Trigger ragdoll a little before the animation early so the character doesn't
// blend back to its normal position.
const float TriggerRagdollTime = DeathAnimDuration - 0.1f;
// Enable blend physics so the bones are properly blending against the montage.
GetMesh()->bBlendPhysics = true;
// Use a local timer handle as we don't need to store it for later but we don't need to look for something to clear
FTimerHandle TimerHandle;
GetWorldTimerManager().SetTimer(TimerHandle, this, &AShooterCharacter::SetRagdollPhysics, FMath::Max(0.1f, TriggerRagdollTime), false);
}
else
{
SetRagdollPhysics();
}
// More code
}
void AShooterCharacter::SetRagdollPhysics()
{
bool bInRagdoll = false;
if (IsPendingKill())
{
bInRagdoll = false;
}
else if (!GetMesh() || !GetMesh()->GetPhysicsAsset())
{
bInRagdoll = false;
}
else
{
// initialize physics/etc
GetMesh()->SetAllBodiesSimulatePhysics(true);
GetMesh()->SetSimulatePhysics(true);
GetMesh()->WakeAllRigidBodies();
GetMesh()->bBlendPhysics = true;
bInRagdoll = true;
}
GetCharacterMovement()->StopMovementImmediately();
GetCharacterMovement()->DisableMovement();
GetCharacterMovement()->SetComponentTickEnabled(false);
if (!bInRagdoll)
{
// hide and set short lifespan
TurnOff();
SetActorHiddenInGame(true);
SetLifeSpan(1.0f);
}
else
{
SetLifeSpan(10.0f);
}
}
There was a still slight pop that we noticed (the characters arm would subtly jerk), but this largely fixed the incident we saw (where the character would flip, and sometimes move away).
I’d recommend taking a look at the above changes to see if there’s any “tunging” that can help. We will continue to look into the jerking issue.
Thanks,
N.