Skip to content
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
12 changes: 12 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -1819,6 +1819,18 @@ description = "Plays an animation from a glTF file with meshes with morph target
category = "Animation"
wasm = true


[[example]]
name = "animated_multiple_time_res"
path = "examples/animation/animated_multiple_time_res.rs"
doc-scrape-examples = true

[package.metadata.example.animated_multiple_time_res]
name = "Animation with different Time resources"
description = "Plays an animations where each of them is using a different Time resource"
category = "Animation"
wasm = true

[[example]]
name = "animated_transform"
path = "examples/animation/animated_transform.rs"
Expand Down
65 changes: 58 additions & 7 deletions crates/bevy_animation/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1043,13 +1043,21 @@ fn trigger_untargeted_animation_events(
}
}

/// Marker component for animations that should not use the default animation time.
Comment thread
alice-i-cecile marked this conversation as resolved.
/// For more details, see the [`TimeDependentAnimationPlugin`] documentation.
#[derive(Debug, Component, Reflect, Clone, Copy, Default)]
#[reflect(Component)]
pub struct ExplicitAnimationTime;

/// A system that advances the time for all playing animations.
pub fn advance_animations(
time: Res<Time>,
pub fn advance_animations<T: Default, F: bevy_ecs::query::QueryFilter>(
time: Res<Time<T>>,
animation_clips: Res<Assets<AnimationClip>>,
animation_graphs: Res<Assets<AnimationGraph>>,
mut players: Query<(&mut AnimationPlayer, &AnimationGraphHandle)>,
) {
mut players: Query<(&mut AnimationPlayer, &AnimationGraphHandle), F>,
) where
Time<T>: Resource,
{
let delta_seconds = time.delta_secs();
players
.par_iter_mut()
Expand Down Expand Up @@ -1306,6 +1314,47 @@ pub fn animate_targets(
}
});
}
/// A plugin that provides animation systems with custom time resources and query filters.
///
/// This plugin allows you to specify which [`Time`] resource to use and which entities
/// to include/exclude from animation updates using [`bevy_ecs::query::QueryFilter`]. This is
/// particularly useful when you want different animations to run on different time scales
/// or exclude certain entities from the default animation pipeline.
///
/// By default, one version is added using [`Time<()>`] and a [`Without`] [`ExplicitAnimationTime`] filter.
pub struct TimeDependentAnimationPlugin<T, F> {
_marker: core::marker::PhantomData<T>,
_marker2: core::marker::PhantomData<F>,
}
impl<T: Default + Send + Sync, F: bevy_ecs::query::QueryFilter + Send + Sync + 'static> Default
for TimeDependentAnimationPlugin<T, F>
where
Time<T>: Resource,
{
fn default() -> Self {
Self {
_marker: core::marker::PhantomData,
_marker2: core::marker::PhantomData,
}
}
}

impl<T: Default + Send + Sync, F: bevy_ecs::query::QueryFilter + Send + Sync + 'static> Plugin
for TimeDependentAnimationPlugin<T, F>
where
Time<T>: Resource,
{
fn build(&self, app: &mut App) {
app.add_systems(
PostUpdate,
(advance_transitions::<T, F>, advance_animations::<T, F>)
.before(animate_targets)
.chain()
.in_set(AnimationSystems)
.before(TransformSystems::Propagate),
);
}
}

/// Adds animation support to an app
#[derive(Default)]
Expand All @@ -1323,8 +1372,6 @@ impl Plugin for AnimationPlugin {
PostUpdate,
(
graph::thread_animation_graphs.before(AssetEventSystems),
advance_transitions,
advance_animations,
// TODO: `animate_targets` can animate anything, so
// ambiguity testing currently considers it ambiguous with
// every other system in `PostUpdate`. We may want to move
Expand All @@ -1338,7 +1385,11 @@ impl Plugin for AnimationPlugin {
.chain()
.in_set(AnimationSystems)
.before(TransformSystems::Propagate),
);
)
.add_plugins(TimeDependentAnimationPlugin::<
(),
Without<ExplicitAnimationTime>,
>::default());
}
}

Expand Down
10 changes: 6 additions & 4 deletions crates/bevy_animation/src/transition.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,10 +108,12 @@ impl AnimationTransitions {

/// A system that alters the weight of currently-playing transitions based on
/// the current time and decline amount.
pub fn advance_transitions(
mut query: Query<(&mut AnimationTransitions, &mut AnimationPlayer)>,
time: Res<Time>,
) {
pub fn advance_transitions<T: Default, F: bevy_ecs::query::QueryFilter>(
mut query: Query<(&mut AnimationTransitions, &mut AnimationPlayer), F>,
time: Res<Time<T>>,
) where
Time<T>: bevy_ecs::resource::Resource,
{
// We use a "greedy layer" system here. The top layer (most recent
// transition) gets as much as weight as it wants, and the remaining amount
// is divided between all the other layers, eventually culminating in the
Expand Down
5 changes: 4 additions & 1 deletion crates/bevy_internal/src/default_plugins.rs
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,10 @@ impl Plugin for IgnoreAmbiguitiesPlugin {
{
app.ignore_ambiguity(
bevy_app::PostUpdate,
bevy_animation::advance_animations,
bevy_animation::advance_animations::<
(),
bevy_ecs::query::Without<bevy_animation::ExplicitAnimationTime>,
>,
bevy_ui::ui_layout_system,
);
app.ignore_ambiguity(
Expand Down
1 change: 1 addition & 0 deletions examples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,7 @@ Example | Description
[Animation Events](../examples/animation/animation_events.rs) | Demonstrate how to use animation events
[Animation Graph](../examples/animation/animation_graph.rs) | Blends multiple animations together with a graph
[Animation Masks](../examples/animation/animation_masks.rs) | Demonstrates animation masks
[Animation with different Time resources](../examples/animation/animated_multiple_time_res.rs) | Plays an animations where each of them is using a different Time resource
[Color animation](../examples/animation/color_animation.rs) | Demonstrates how to animate colors using mixing and splines in different color spaces
[Custom Skinned Mesh](../examples/animation/custom_skinned_mesh.rs) | Skinned mesh example with mesh and joints data defined in code
[Eased Motion](../examples/animation/eased_motion.rs) | Demonstrates the application of easing curves to animate an object
Expand Down
Loading
Loading