diff --git a/src/extrapolation.rs b/src/extrapolation.rs index b138f7d..00143e9 100644 --- a/src/extrapolation.rs +++ b/src/extrapolation.rs @@ -83,7 +83,7 @@ use bevy::prelude::*; /// Then, add the [`TransformExtrapolationPlugin`] to the app with the velocity sources: /// /// ``` -/// use bevy::{ecs::query::QueryData, prelude::*}; +/// use bevy::{ecs::query::QueryData, time::TimePlugin, prelude::*}; /// use bevy_transform_interpolation::{prelude::*, VelocitySource}; /// # /// # #[derive(Component, Default)] @@ -128,6 +128,7 @@ use bevy::prelude::*; /// let mut app = App::new(); /// /// app.add_plugins(( +/// TimePlugin, /// TransformInterpolationPlugin::default(), /// TransformExtrapolationPlugin::::default(), /// )); @@ -324,7 +325,7 @@ impl Plugin // Add the `TransformEasingPlugin` if it hasn't been added yet. // It performs the actual easing based on the start and end states set by the extrapolation. if !app.is_plugin_added::() { - app.add_plugins(TransformEasingPlugin); + app.add_plugins(TransformEasingPlugin::default()); } } } diff --git a/src/hermite.rs b/src/hermite.rs index 6333a6c..c31168e 100644 --- a/src/hermite.rs +++ b/src/hermite.rs @@ -92,7 +92,7 @@ use crate::{ /// along with the [`TransformInterpolationPlugin`] and/or [`TransformExtrapolationPlugin`]: /// /// ``` -/// use bevy::{ecs::query::QueryData, prelude::*}; +/// use bevy::{ecs::query::QueryData, time::TimePlugin, prelude::*}; /// use bevy_transform_interpolation::{prelude::*, VelocitySource}; /// # /// # #[derive(Component, Default)] @@ -144,6 +144,7 @@ use crate::{ /// let mut app = App::new(); /// /// app.add_plugins(( +/// TimePlugin, /// TransformInterpolationPlugin::default(), /// TransformHermiteEasingPlugin::::default(), /// )); diff --git a/src/interpolation.rs b/src/interpolation.rs index 27bc0d5..07cd3d4 100644 --- a/src/interpolation.rs +++ b/src/interpolation.rs @@ -8,7 +8,10 @@ use crate::{ prelude::*, RotationEasingState, ScaleEasingState, TransformEasingSet, TranslationEasingState, }; -use bevy::prelude::*; +use bevy::{ + ecs::schedule::{InternedScheduleLabel, ScheduleLabel}, + prelude::*, +}; /// A plugin for [`Transform`] interpolation, making movement in [`FixedUpdate`] appear smooth. /// @@ -80,6 +83,7 @@ use bevy::prelude::*; /// interpolate_translation_all: true, /// interpolate_rotation_all: true, /// interpolate_scale_all: false, +/// ..Default::default() /// }) /// // ... /// .run(); @@ -115,7 +119,7 @@ use bevy::prelude::*; /// If the previous and current velocities are also available, it is possible to use [Hermite interpolation] /// with the [`TransformHermiteEasingPlugin`] to get smoother and more accurate easing. To enable Hermite interpolation, /// add the [`TransformHermiteEasing`] component to the entity in addition to the core interpolation components. -#[derive(Debug, Default)] +#[derive(Debug)] pub struct TransformInterpolationPlugin { /// If `true`, translation will be interpolated for all entities with the [`Transform`] component by default. /// @@ -129,6 +133,23 @@ pub struct TransformInterpolationPlugin { /// /// This can be overridden for individual entities by adding the [`NoScaleEasing`] or [`NoTransformEasing`] component. pub interpolate_scale_all: bool, + + /// The schedule which runs at the start of an executed fixed timestep, defaults to [`FixedFirst`]. + pub schedule_fixed_first: InternedScheduleLabel, + /// The schedule which runs at the end of an executed fixed timestep, defaults to [`FixedLast`]. + pub schedule_fixed_last: InternedScheduleLabel, +} + +impl Default for TransformInterpolationPlugin { + fn default() -> Self { + Self { + interpolate_translation_all: false, + interpolate_rotation_all: false, + interpolate_scale_all: false, + schedule_fixed_first: FixedFirst.intern(), + schedule_fixed_last: FixedLast.intern(), + } + } } impl TransformInterpolationPlugin { @@ -136,11 +157,12 @@ impl TransformInterpolationPlugin { /// /// This can be overridden for individual entities by adding the [`NoTransformEasing`] component, /// or the individual [`NoTranslationEasing`], [`NoRotationEasing`], and [`NoScaleEasing`] components. - pub const fn interpolate_all() -> Self { + pub fn interpolate_all() -> Self { Self { interpolate_translation_all: true, interpolate_rotation_all: true, interpolate_scale_all: true, + ..Default::default() } } } @@ -155,7 +177,7 @@ impl Plugin for TransformInterpolationPlugin { )>(); app.add_systems( - FixedFirst, + self.schedule_fixed_first, ( complete_translation_easing, complete_rotation_easing, @@ -164,10 +186,9 @@ impl Plugin for TransformInterpolationPlugin { .chain() .before(TransformEasingSet::Reset), ); - // Update the start state of the interpolation at the start of the fixed timestep. app.add_systems( - FixedFirst, + self.schedule_fixed_first, ( update_translation_interpolation_start, update_rotation_interpolation_start, @@ -179,7 +200,7 @@ impl Plugin for TransformInterpolationPlugin { // Update the end state of the interpolation at the end of the fixed timestep. app.add_systems( - FixedLast, + self.schedule_fixed_last, ( update_translation_interpolation_end, update_rotation_interpolation_end, @@ -205,7 +226,7 @@ impl Plugin for TransformInterpolationPlugin { fn finish(&self, app: &mut App) { // Add the `TransformEasingPlugin` if it hasn't been added yet. if !app.is_plugin_added::() { - app.add_plugins(TransformEasingPlugin); + app.add_plugins(TransformEasingPlugin::default()); } } } diff --git a/src/lib.rs b/src/lib.rs index ef2b022..6ad9272 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -58,11 +58,12 @@ //! //! ``` //! # use bevy::prelude::*; +//! # use bevy::time::TimePlugin; //! # use bevy_transform_interpolation::prelude::*; //! # //! fn main() { //! App::new() -//! .add_plugins(TransformInterpolationPlugin::interpolate_all()) +//! .add_plugins((TimePlugin, TransformInterpolationPlugin::interpolate_all())) //! // ... //! .run(); //! } @@ -159,7 +160,12 @@ use extrapolation::*; use interpolation::*; use bevy::{ - ecs::{component::Tick, query::QueryData, system::SystemChangeTick}, + ecs::{ + component::Tick, + query::QueryData, + schedule::{InternedScheduleLabel, InternedSystemSet, ScheduleLabel}, + system::SystemChangeTick, + }, prelude::*, }; @@ -171,8 +177,31 @@ use bevy::{ /// /// To actually perform automatic easing, an easing backend that updates the `start` and `end` states must be used. /// The [`TransformInterpolationPlugin`] is provided for transform interpolation, but custom backends can also be implemented. -#[derive(Debug, Default)] -pub struct TransformEasingPlugin; +#[derive(Debug)] +pub struct TransformEasingPlugin { + /// The schedule which runs at the start of an executed fixed timestep, defaults to [`FixedFirst`]. + pub schedule_fixed_first: InternedScheduleLabel, + /// The schedule which runs at the end of an executed fixed timestep, defaults to [`FixedLast`]. + pub schedule_fixed_last: InternedScheduleLabel, + /// The schedule which runs each frame, during the fixed timestep logic, defaults to [`RunFixedMainLoop`]. + pub schedule_fixed_loop: InternedScheduleLabel, + /// The schedule which runs each frame, after the fixed timestep logic, defaults to [`RunFixedMainLoopSystem::AfterFixedMainLoop`]. + pub after_fixed_main_loop: InternedSystemSet, + /// If set to `true`, the plugin adds systems to update the easing values in [`TransformEasingSet::Ease`]. + pub update_easing_values: bool, +} + +impl Default for TransformEasingPlugin { + fn default() -> Self { + Self { + schedule_fixed_first: FixedFirst.intern(), + schedule_fixed_last: FixedLast.intern(), + schedule_fixed_loop: RunFixedMainLoop.intern(), + after_fixed_main_loop: RunFixedMainLoopSystem::AfterFixedMainLoop.intern(), + update_easing_values: true, + } + } +} impl Plugin for TransformEasingPlugin { fn build(&self, app: &mut App) { @@ -190,27 +219,27 @@ impl Plugin for TransformEasingPlugin { // Reset easing states and update start values at the start of the fixed timestep. app.configure_sets( - FixedFirst, + self.schedule_fixed_first, (TransformEasingSet::Reset, TransformEasingSet::UpdateStart).chain(), ); // Update end values at the end of the fixed timestep. - app.configure_sets(FixedLast, TransformEasingSet::UpdateEnd); + app.configure_sets(self.schedule_fixed_last, TransformEasingSet::UpdateEnd); // Perform transform easing right after the fixed timestep, before `Update`. app.configure_sets( - RunFixedMainLoop, + self.schedule_fixed_loop, ( TransformEasingSet::Ease, TransformEasingSet::UpdateEasingTick, ) .chain() - .in_set(RunFixedMainLoopSystem::AfterFixedMainLoop), + .in_set(self.after_fixed_main_loop), ); // Reset easing states. app.add_systems( - FixedFirst, + self.schedule_fixed_first, ( reset_translation_easing, reset_rotation_easing, @@ -221,20 +250,22 @@ impl Plugin for TransformEasingPlugin { ); app.add_systems( - RunFixedMainLoop, + self.schedule_fixed_loop, reset_easing_states_on_transform_change.before(TransformEasingSet::Ease), ); - // Perform easing. - app.add_systems( - RunFixedMainLoop, - (ease_translation_lerp, ease_rotation_slerp, ease_scale_lerp) - .in_set(TransformEasingSet::Ease), - ); + if self.update_easing_values { + // Perform easing. + app.add_systems( + self.schedule_fixed_loop, + (ease_translation_lerp, ease_rotation_slerp, ease_scale_lerp) + .in_set(TransformEasingSet::Ease), + ); + } // Update the last easing tick. app.add_systems( - RunFixedMainLoop, + self.schedule_fixed_loop, update_last_easing_tick.in_set(TransformEasingSet::UpdateEasingTick), ); }