Skip to content

Conversation

@atornity
Copy link
Contributor

@atornity atornity commented Sep 30, 2024

Objective

Add support for events that can be triggered from animation clips. This is useful when you need something to happen at a specific time in an animation. For example, playing a sound every time a characters feet hits the ground when walking.

Closes #15494

Solution

Added a new field to AnimationClip: events, which contains a list of AnimationEvents. These are automatically triggered in animate_targets and trigger_untargeted_animation_events.

Testing

Added a couple of tests and example (animation_events.rs) to make sure events are triggered when expected.


Showcase

Events need to also implement AnimationEvent and Reflect to be used with animations.

#[derive(Event, AnimationEvent, Reflect)]
struct SomeEvent;

Events can be added to an AnimationClip by specifying a time and event.

// trigger an event after 1.0 second
animation_clip.add_event(1.0, SomeEvent);

And optionally, providing a target id.

let id = AnimationTargetId::from_iter(["shoulder", "arm", "hand"]);
animation_clip.add_event_to_target(id, 1.0, HandEvent);

I modified the animated_fox example to show off the feature.

CleanShot 2024-10-05 at 02 41 57

@alice-i-cecile alice-i-cecile added C-Feature A new feature, making something new possible A-Animation Make things move and change over time S-Waiting-on-Author The author needs to make changes or address concerns before this can be merged labels Sep 30, 2024
@github-actions
Copy link
Contributor

The generated examples/README.md is out of sync with the example metadata in Cargo.toml or the example readme template. Please run cargo run -p build-templated-pages -- update examples to update it, and commit the file change.

@github-actions
Copy link
Contributor

The generated examples/README.md is out of sync with the example metadata in Cargo.toml or the example readme template. Please run cargo run -p build-templated-pages -- update examples to update it, and commit the file change.

@atornity atornity force-pushed the animation-triggers-experiments branch from eda8fe2 to d2ed656 Compare September 30, 2024 21:11
@mockersf
Copy link
Member

mockersf commented Oct 4, 2024

I would prefer to not add a new model, would it be possible to work with the animated fox in examples?

if not, the model should be added to https://github.com/bevyengine/bevy/blob/main/CREDITS.md with its licence and a link to the opengameart.org page

@atornity
Copy link
Contributor Author

atornity commented Oct 4, 2024

I would prefer to not add a new model, would it be possible to work with the animated fox in examples?

if not, the model should be added to https://github.com/bevyengine/bevy/blob/main/CREDITS.md with its licence and a link to the opengameart.org page

That seems doable. would you prefer I added events to the existing animated_fox example in that case? It would be two mostly identical examples otherwise, although the animated_fox example would become quite large if I did that.

@atornity
Copy link
Contributor Author

atornity commented Oct 5, 2024

I removed the bunny_detective example and added animation events to the animated_fox example instead.

Copy link
Contributor

@ChristopherBiscardi ChristopherBiscardi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall love this feature, I've written implementations in my games for it in the past. I ran the examples (including the older ones that got removed) and feel like adding events is very usable.

I'm curious if the difference between manual impls and derived impls running at different times will be a pain point for learning the feature from examples.

One thing I wonder about is timeframe vs frame count for add_event. Will the time offset scale if time is sped up/slowed down (such as for a slow-motion effect)? and how does someone figure out what the time offset is supposed to be? If I was building an animation in another program wouldn't it be more likely that I was calculating it based on the frame data? Perhaps time and frame versions of specifying could be useful.

@atornity
Copy link
Contributor Author

atornity commented Oct 5, 2024

I'm curious if the difference between manual impls and derived impls running at different times will be a pain point for learning the feature from examples.

Yep, it was a bad idea on my part to make an example that required a custom implementation since it modifies Text. Although it did work with the derive, it just annoyed me that the color would change one frame before the text. On the other hand, it does demonstrate how to manually implement the trait, witch is more powerful anyways.

One thing I wonder about is timeframe vs frame count for add_event. Will the time offset scale if time is sped up/slowed down (such as for a slow-motion effect)? and how does someone figure out what the time offset is supposed to be? If I was building an animation in another program wouldn't it be more likely that I was calculating it based on the frame data? Perhaps time and frame versions of specifying could be useful.

In the bunny example I had a comment that explained how to determine the correct time, it's essentially frame index / fps of animation (regardless of playback speed), I'll see if I can add that to the fox example as well.
You can use up and down keys in the fox example btw, to see it's still working when playing in slow motion or sped up.

As for an alternate add_event version where you specify the frame the event should occur. That sounds super useful to me. I don't think I'll be adding that in this PR though as I'm not sure how to retrieve (or if it's possible) the fps of an animation.

@mockersf mockersf enabled auto-merge October 6, 2024 09:53
@mockersf mockersf added this pull request to the merge queue Oct 6, 2024
Merged via the queue into bevyengine:main with commit d9190e4 Oct 6, 2024
github-merge-queue bot pushed a commit that referenced this pull request Oct 6, 2024
# Objective

Pausing the `animated_fox` example perfectly as one of the feet hits the
ground causes the event to be triggered every frame.

Context: #15538

## Solution

Don't trigger animation events if the animation is paused.

## Testing

Ran the example, I no longer see the issue.
@alice-i-cecile
Copy link
Member

Thank you to everyone involved with the authoring or reviewing of this PR! This work is relatively important and needs release notes! Head over to bevyengine/bevy-website#1716 if you'd like to help out.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-Animation Make things move and change over time C-Feature A new feature, making something new possible M-Release-Note Work that should be called out in the blog due to impact S-Ready-For-Final-Review This PR has been approved by the community. It's ready for a maintainer to consider merging it

Projects

None yet

Development

Successfully merging this pull request may close these issues.

animation triggers/events

6 participants