Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

API updates to the AnimationPlayer #9002

Merged
merged 31 commits into from
Aug 28, 2023
Merged
Changes from 1 commit
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
e663e51
RepeatAnimation, is_playback_reversed(), is_finished(), animation upd…
DevinLeamy Jun 30, 2023
a6488df
Apply modulo to elapsed time
DevinLeamy Jun 30, 2023
169a94c
Greater than or equals
DevinLeamy Jun 30, 2023
1400461
lint
DevinLeamy Jun 30, 2023
6e3b15c
Updated names and comments
DevinLeamy Jun 30, 2023
eec1240
Typo
DevinLeamy Jun 30, 2023
a9f82a3
Added animation_clip() accessor and made animation_clip optional
DevinLeamy Jul 1, 2023
a920e90
lint
DevinLeamy Jul 1, 2023
57df0ac
Updated comment
DevinLeamy Jul 1, 2023
5af3277
Conditionally update the elapsed time
DevinLeamy Jul 1, 2023
1d829db
repeat_mode() and completions() public accessors
DevinLeamy Jul 1, 2023
3ad8d27
Updated comment
DevinLeamy Jul 1, 2023
62c67e5
Implement default for RepeatAnimation, with Never as the default
DevinLeamy Aug 16, 2023
d36d5bc
Renamed PlayingAnimation::finished to PlayingAnimation::is_finished t…
DevinLeamy Aug 16, 2023
a3a7eb4
animation_clip: Handle<AnimationClip>, rather than Option<Handle<Anim…
DevinLeamy Aug 16, 2023
60fc68c
Introduced seek_time and PlayingAnimation::update()
DevinLeamy Aug 16, 2023
63a71b6
Introduced AnimationPlayer::replay() to reset the PlayingAnimation's …
DevinLeamy Aug 17, 2023
88fd036
Removed AnimationPlayer::stop_repeating() and added a comment to Anim…
DevinLeamy Aug 17, 2023
764ae7e
Updated examples
DevinLeamy Aug 17, 2023
e028c17
Remove unused import
DevinLeamy Aug 17, 2023
f09ce88
Merge branch 'main' of https://github.com/bevyengine/bevy into animat…
DevinLeamy Aug 17, 2023
9670723
nit: fix comment
DevinLeamy Aug 17, 2023
1d2a9b9
Nit: improved comment
DevinLeamy Aug 17, 2023
d59789b
Replaced deprecated for_each_mut with for_each
DevinLeamy Aug 18, 2023
011d13f
Updated animated_fox example to showcase the repeat modes
DevinLeamy Aug 18, 2023
5b8da3f
Merge branch 'animation-api' of https://github.com/DevinLeamy/bevy in…
DevinLeamy Aug 18, 2023
f52c991
Merge branch 'main' of https://github.com/bevyengine/bevy into animat…
DevinLeamy Aug 18, 2023
7910f05
nit: format
DevinLeamy Aug 18, 2023
6527d72
Reformat comments + re-run CI, post moving run-examples over to windows
DevinLeamy Aug 22, 2023
f50c8c4
nit: cargo fmt --all
DevinLeamy Aug 22, 2023
8d3b642
Applied suggestions (updates to comments and inlines)
DevinLeamy Aug 24, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 48 additions & 5 deletions crates/bevy_animation/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -123,23 +123,38 @@ impl AnimationClip {
}
}

/// Repetition behavior of the animation.
#[derive(Reflect, Copy, Clone)]
pub enum RepeatAnimation {
/// Repeat forever.
Forever,
/// Repeat forever.
Once,
DevinLeamy marked this conversation as resolved.
Show resolved Hide resolved
/// Repeat "n" times.
Count(u32),
}

#[derive(Reflect)]
struct PlayingAnimation {
repeat: bool,
repeat: RepeatAnimation,
speed: f32,
elapsed: f32,
animation_clip: Handle<AnimationClip>,
path_cache: Vec<Vec<Option<Entity>>>,
/// Number of times the animation has completed.
/// If the animation is playing in reverse, this increments when the animation passes the start.
completions: u32,
DevinLeamy marked this conversation as resolved.
Show resolved Hide resolved
}

impl Default for PlayingAnimation {
fn default() -> Self {
Self {
repeat: false,
repeat: RepeatAnimation::Once,
speed: 1.0,
elapsed: 0.0,
animation_clip: Default::default(),
path_cache: Vec::new(),
completions: 0,
}
}
}
Expand Down Expand Up @@ -212,6 +227,16 @@ impl AnimationPlayer {
self
}

/// Predicate to check if the animation has finished, based on its repetition behavior and the number of times it has repeated.
/// Note: A repeating will never finish.
pub fn is_finished(&self) -> bool {
match self.animation.repeat {
RepeatAnimation::Forever => false,
RepeatAnimation::Once => self.animation.completions >= 1,
RepeatAnimation::Count(n) => self.animation.completions >= n,
}
}

/// Start playing an animation, resetting state of the player, unless the requested animation is already playing.
/// If `transition_duration` is set, this will use a linear blending
/// between the previous and the new animation to make a smooth transition
Expand All @@ -237,16 +262,27 @@ impl AnimationPlayer {

/// Set the animation to repeat
pub fn repeat(&mut self) -> &mut Self {
self.animation.repeat = true;
self.animation.repeat = RepeatAnimation::Forever;
self
}

/// Stop the animation from repeating
pub fn stop_repeating(&mut self) -> &mut Self {
self.animation.repeat = false;
self.animation.repeat = RepeatAnimation::Once;
self
}

/// Set the repetition behaviour of the animation
pub fn set_repeat(&mut self, repeat: RepeatAnimation) -> &mut Self {
self.animation.repeat = repeat;
self
}

/// Predicate to check if the animation is playing in reverse.
DevinLeamy marked this conversation as resolved.
Show resolved Hide resolved
pub fn is_playback_reversed(&self) -> bool {
self.animation.speed < 0.0
}

/// Pause the animation
pub fn pause(&mut self) {
self.paused = true;
Expand Down Expand Up @@ -483,7 +519,14 @@ fn apply_animation(
animation.elapsed += time.delta_seconds() * animation.speed;
}
let mut elapsed = animation.elapsed;
if animation.repeat {

if elapsed > animation_clip.duration && animation.speed > 0.0 {
animation.completions += 1;
} else if elapsed < 0.0 && animation.speed < 0.0 {
animation.completions += 1;
}

if matches!(animation.repeat, RepeatAnimation::Forever) {
elapsed %= animation_clip.duration;
}
if elapsed < 0.0 {
Expand Down