Making bones teleport in an exporter skeletal animation

We have some skeletal animations in which bones occasionally need to teleport to a different location. In Blender this is easy to set up: we just set the keyframe to step/constant and then instead of going smoothly between two positions, it teleports. However, when we export this to Unreal, Unreal interpolates in the time between frames so the bones are seen moving very quickly, even when the keyframes are directly next to each other.

I found in [this [Content removed] that Unreal apparently does not support mixing linear and step interpolation in a single animation, is that indeed true?

I wouldn’t mind turning off interpolation altogether for this specific animation so we tried to set the Interpolation type on the entire animation to Step, but even then we see the bone move instead of teleporting. We only see this in-game; we don’t see this in Unreal’s animation viewer (I imagine because the viewer is glued to the animation framerate and doesn’t show in-between frames?). Does this option not do what I think it does?

[Image Removed]

How can we make specific bones teleport at specific moments within a skeletal animation?

Steps to Reproduce
I can provide an animation file with this issue if needed.

Hey,

It is true that in animations imported from an external source, the curves are assumed to have linear interpolation as the default, so the tangents are set that way. You can do a few things to get the behaviour you’re looking for.

I wouldn’t mind turning off interpolation altogether for this specific animation so we tried to set the Interpolation type on the entire animation to Step, but even then we see the bone move instead of teleporting.

This does work for every animation I’ve tested, so you might consider sending me a file to test this on, just in case.

The other option is that you can import the file and then edit the curves of your animation using:

[Image Removed]From here, you would follow the prompt to bake down the animation to the FK Rig (the bones). Then, you can modify the tangents of the areas that you want to have teleport, and then save the file.

[Image Removed]Hopefully, that gets you what you want.

If you are considering this for a cinematic sequence in a runtime game during camera cuts, I recommend using the shot system instead. Using the bone for teleportation doesn’t provide all the necessary information to other systems like cloth and motion vectors during camera cuts, and you can end up with blurry frames or cloth/physics popping.

Hi Dustin,

Thanks for the quick and clear reply!

We have several animations with this issue. For some it sounds like this will indeed be the fix.

However, we also have dozens of building construction animations. These are generated using a script in Blender and have around one thousand bones each. Fixing this by hand for all of those is not doable. We will try the Step setting on those animations again, if that still doesn’t work I will share the file.

(This isn’t about cinematics, by the way.)

We did some more experimentation and apparently setting Step interpolation on the entire animation in Unreal does work as intended, but NOT when Update Rate Optimization is enabled on the animation: then we see the interpolated moments in between the keyframes again. So maybe Unreal has a bug in combining Step interpolation with Update Rate Optimization?

Yes good catch. There is a cvar where you can turn it off:

a.URO.DisableInterpolationthe downside to this approach is that it will disable it for everything. You could modify USkeletalMeshComponent::RefreshBoneTransforms :

const bool bShouldInterpolateSkippedFrames = (bExternalTickRateControlled && bExternalInterpolate) || (bCachedShouldUseUpdateRateOptimizations && AnimUpdateRateParams->ShouldInterpolateSkippedFrames());to override that behaviour per mesh.

Another option would be to setup the URO parameters to have a MaxEvalRateForInterpolation. You could subclass the USkeletalMeshComponent and then hook into the OnAnimUpdateRateParamsCreated delegate to override that property for your exact specifications. Something along the lines of:

`NewPawn::NewPawn(const FObjectInitializer& ObjectInitializer)
: Super(ObjectInitializer.SetDefaultSubobjectClass(ACharacter::CharacterMovementComponentName))
, bEnableUpdateRateOptimizations(true)
, bDisplayDebugUpdateRateOptimizations(true)
{
USkeletalMeshComponent* CharMesh = GetMesh();
CharMesh->OnAnimUpdateRateParamsCreated.BindUObject(this, &AQALODPawn::OnAnimUpdateRateParamsCreated);
}

void NewPawn::OnAnimUpdateRateParamsCreated(FAnimUpdateRateParameters* MeshAnimUpdateRateParams)
{
if (MeshAnimUpdateRateParams)
{
USkeletalMeshComponent* CharMesh = GetMesh();
CharMesh->bEnableUpdateRateOptimizations = bEnableUpdateRateOptimizations;
CharMesh->bDisplayDebugUpdateRateOptimizations = bDisplayDebugUpdateRateOptimizations;

MeshAnimUpdateRateParams->MaxEvalRateForInterpolation = MaxEvalRateForInterpolation;
}
}`

Thanks for the very extensive solution! Disabling interpolation for everything isn’t great I think since the majority of our animations would look better with interpolation. So the subclassing of USkeletalMeshComponent sounds like the more suitable solution for us.

For now we’ve kept it simple and have changed the animation to hide the teleporting: the bones are now scale 0.001 during the teleporting and then scale up again, essentially hiding the problem of interpolation during teleportation.

Excellent, glad I could be of service, and you found something that works for you.

Dustin