bevy/examples/animation
Patrick Walton 8154164f1b
Allow animation clips to animate arbitrary properties. (#15282)
Currently, Bevy restricts animation clips to animating
`Transform::translation`, `Transform::rotation`, `Transform::scale`, or
`MorphWeights`, which correspond to the properties that glTF can
animate. This is insufficient for many use cases such as animating UI,
as the UI layout systems expect to have exclusive control over UI
elements' `Transform`s and therefore the `Style` properties must be
animated instead.

This commit fixes this, allowing for `AnimationClip`s to animate
arbitrary properties. The `Keyframes` structure has been turned into a
low-level trait that can be implemented to achieve arbitrary animation
behavior. Along with `Keyframes`, this patch adds a higher-level trait,
`AnimatableProperty`, that simplifies the task of animating single
interpolable properties. Built-in `Keyframes` implementations exist for
translation, rotation, scale, and morph weights. For the most part, you
can migrate by simply changing your code from
`Keyframes::Translation(...)` to `TranslationKeyframes(...)`, and
likewise for rotation, scale, and morph weights.

An example `AnimatableProperty` implementation for the font size of a
text section follows:

     #[derive(Reflect)]
     struct FontSizeProperty;

     impl AnimatableProperty for FontSizeProperty {
         type Component = Text;
         type Property = f32;
fn get_mut(component: &mut Self::Component) -> Option<&mut
Self::Property> {
             Some(&mut component.sections.get_mut(0)?.style.font_size)
         }
     }

In order to keep this patch relatively small, this patch doesn't include
an implementation of `AnimatableProperty` on top of the reflection
system. That can be a follow-up.

This patch builds on top of the new `EntityMutExcept<>` type in order to
widen the `AnimationTarget` query to include write access to all
components. Because `EntityMutExcept<>` has some performance overhead
over an explicit query, we continue to explicitly query `Transform` in
order to avoid regressing the performance of skeletal animation, such as
the `many_foxes` benchmark. I've measured the performance of that
benchmark and have found no significant regressions.

A new example, `animated_ui`, has been added. This example shows how to
use Bevy's built-in animation infrastructure to animate font size and
color, which wasn't possible before this patch.

## Showcase


https://github.com/user-attachments/assets/1fa73492-a9ce-405a-a8f2-4aacd7f6dc97

## Migration Guide

* Animation keyframes are now an extensible trait, not an enum. Replace
`Keyframes::Translation(...)`, `Keyframes::Scale(...)`,
`Keyframes::Rotation(...)`, and `Keyframes::Weights(...)` with
`Box::new(TranslationKeyframes(...))`, `Box::new(ScaleKeyframes(...))`,
`Box::new(RotationKeyframes(...))`, and
`Box::new(MorphWeightsKeyframes(...))` respectively.
2024-09-23 17:14:12 +00:00
..
animated_fox.rs Add AnimationGraph::from_clips and simplify animated_fox example (#14853) 2024-08-25 14:16:04 +00:00
animated_transform.rs Allow animation clips to animate arbitrary properties. (#15282) 2024-09-23 17:14:12 +00:00
animated_ui.rs Allow animation clips to animate arbitrary properties. (#15282) 2024-09-23 17:14:12 +00:00
animation_graph.rs Have EntityCommands methods consume self for easier chaining (#14897) 2024-08-26 18:24:59 +00:00
animation_masks.rs Fix some examples having different instruction text positions (#15017) 2024-09-02 22:48:48 +00:00
color_animation.rs Fix floating point math (#15239) 2024-09-16 23:28:12 +00:00
cubic_curve.rs Fix floating point math (#15239) 2024-09-16 23:28:12 +00:00
custom_skinned_mesh.rs Fix floating point math (#15239) 2024-09-16 23:28:12 +00:00
gltf_skinned_mesh.rs Fix floating point math (#15239) 2024-09-16 23:28:12 +00:00
morph_targets.rs glTF labels: add enum to avoid misspelling and keep up-to-date list documented (#13586) 2024-05-31 23:25:57 +00:00