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

add remove_on_completed flag and new_self_removing fn to Animator and AssetAnimator #122

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
31 changes: 31 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -421,6 +421,14 @@ macro_rules! animator_impl {
self
}

/// Indicate whether the Animator component should be removed from entity
/// after reaching [`TweenState::Completed`].
#[must_use]
pub fn with_remove_on_completed(mut self, remove: bool) -> Self {
self.remove_on_completed = remove;
self
}

/// Set the animation speed. Defaults to 1.
///
/// A speed of 2 means the animation will run twice as fast while a speed of 0.1
Expand Down Expand Up @@ -476,6 +484,7 @@ pub struct Animator<T: Component> {
pub state: AnimatorState,
tweenable: BoxedTweenable<T>,
speed: f32,
remove_on_completed: bool,
}

impl<T: Component + std::fmt::Debug> std::fmt::Debug for Animator<T> {
Expand All @@ -494,9 +503,17 @@ impl<T: Component> Animator<T> {
state: default(),
tweenable: Box::new(tween),
speed: 1.,
remove_on_completed: false,
}
}

/// Create a new animator component from a single tweenable.
/// After [`TweenState::Completed`] reached the component is removed from entity
#[must_use]
pub fn new_self_removing(tween: impl Tweenable<T> + 'static) -> Self {
Self::new(tween).with_remove_on_completed(true)
}

animator_impl!();
}

Expand All @@ -511,6 +528,7 @@ pub struct AssetAnimator<T: Asset> {
pub state: AnimatorState,
tweenable: BoxedTweenable<T>,
speed: f32,
remove_on_completed: bool,
}

#[cfg(feature = "bevy_asset")]
Expand All @@ -531,6 +549,19 @@ impl<T: Asset> AssetAnimator<T> {
state: default(),
tweenable: Box::new(tween),
speed: 1.,
remove_on_completed: false,
}
}

/// Create a new animator component from a single tweenable.
/// After [`TweenState::Completed`] reached the component is removed from entity
#[must_use]
pub fn new_self_removing(tween: impl Tweenable<T> + 'static) -> Self {
Self {
state: default(),
tweenable: Box::new(tween),
speed: 1.,
remove_on_completed: true,
}
}

Expand Down
14 changes: 11 additions & 3 deletions src/plugin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use bevy::prelude::*;

#[cfg(feature = "bevy_asset")]
use crate::{tweenable::AssetTarget, AssetAnimator};
use crate::{tweenable::ComponentTarget, Animator, AnimatorState, TweenCompleted};
use crate::{tweenable::ComponentTarget, Animator, AnimatorState, TweenCompleted, TweenState};

/// Plugin to add systems related to tweening of common components and assets.
///
Expand Down Expand Up @@ -88,18 +88,22 @@ pub fn component_animator_system<T: Component>(
time: Res<Time>,
mut query: Query<(Entity, &mut T, &mut Animator<T>)>,
events: ResMut<Events<TweenCompleted>>,
mut commands: Commands,
) {
let mut events: Mut<Events<TweenCompleted>> = events.into();
for (entity, target, mut animator) in query.iter_mut() {
if animator.state != AnimatorState::Paused {
let speed = animator.speed();
let mut target = ComponentTarget::new(target);
animator.tweenable_mut().tick(
let tween_state = animator.tweenable_mut().tick(
time.delta().mul_f32(speed),
&mut target,
entity,
&mut events,
);
if tween_state == TweenState::Completed && animator.remove_on_completed {
commands.entity(entity).remove::<Animator<T>>();
}
}
}
}
Expand All @@ -116,6 +120,7 @@ pub fn asset_animator_system<T: Asset>(
assets: ResMut<Assets<T>>,
mut query: Query<(Entity, &Handle<T>, &mut AssetAnimator<T>)>,
events: ResMut<Events<TweenCompleted>>,
mut commands: Commands,
) {
let mut events: Mut<Events<TweenCompleted>> = events.into();
let mut target = AssetTarget::new(assets);
Expand All @@ -126,12 +131,15 @@ pub fn asset_animator_system<T: Asset>(
continue;
}
let speed = animator.speed();
animator.tweenable_mut().tick(
let tween_state = animator.tweenable_mut().tick(
time.delta().mul_f32(speed),
&mut target,
entity,
&mut events,
);
if tween_state == TweenState::Completed && animator.remove_on_completed {
commands.entity(entity).remove::<AssetAnimator<T>>();
}
}
}
}
Expand Down