Last Frame of UMG Animation Skipped

Article written by Austin C.

When playing back a UMG animation with a keyframe at the very end, the animation may not play to completion, leaving parameters at unexpected values. For example, animating opacity from 1 to 0 may result in a very faint, but still visible bit of UI that should be completely invisible if the 0 key was applied at the very end of the animation. This is more pronounced at lower framerates.

This behavior is due to UMG animations using float based timing for playback, and the default settings for the UMG animation editor. When adding a key to the very end of an animation, by default the animation is automatically stretched out slightly to accommodate that key, which can lead to rounding errors when frame based animations are played back using float based time values.

The underlying times of the sequence representing the UMG animation are stored as integers each representing one frame, or tick. A key represents the start of a tick, so a key at the end of the playback range would not be evaluated, because that tick would never happen, as it starts after the playback range, unless the range is adjusted to contain that key.

For instance, in the case that playback ends at 1 second, playing the animation evaluates all keys up to, but not including those that fall on second 1, as evaluating that key would last for one tick after second 1.

By default in UMG animations, if a key is added at second 1, the playback is automatically expanded to end at 1 second and one tick, so the key will be included in playback. This can be disabled by unchecking “Keep Playback Range in Section Bounds” in the Playback menu of the UMG animation timeline (Triangular play drop-down menu in the timeline toolbar). With this disabled the timing of the UMG animation will no longer automatically expand as keys are added to the end.

When enabled, this setting automatically expands the animation length, which is desirable for some workflows. In general, a more advanced workflow will have it disabled, so it’s left on as a default for simpler workflows.

One trick is to trigger an event once the animation is complete and set the final state of any animated component. It requires more effort, but it will guarantee that the items remain in an intended state.