bevy_transform_interpolation::prelude

Struct TransformInterpolationPlugin

source
pub struct TransformInterpolationPlugin {
    pub interpolate_translation_all: bool,
    pub interpolate_rotation_all: bool,
    pub interpolate_scale_all: bool,
}
Expand description

A plugin for Transform interpolation, making movement in FixedUpdate appear smooth.

Transform interpolation applies easing between the old and current Transform in between fixed timesteps. This results in movement that looks smooth and accurate, at the cost of rendered positions being slightly behind the “true” gameplay positions.

This plugin requires the TransformEasingPlugin to function. It is automatically added if not already present in the app.

§Usage

Transform interpolation can be enabled for a given entity by adding the TransformInterpolation component.

use bevy::prelude::*;
use bevy_transform_interpolation::prelude::*;

fn setup(mut commands: Commands) {
    // Interpolate the entire transform: translation, rotation, and scale.
    commands.spawn((
        Transform::default(),
        TransformInterpolation,
    ));
}

Now, any changes made to the Transform of the entity in FixedPreUpdate, FixedUpdate, or FixedPostUpdate will automatically be smoothed in between fixed timesteps.

Transform properties can also be interpolated individually by adding the TranslationInterpolation, RotationInterpolation, and ScaleInterpolation components.

fn setup(mut commands: Commands) {
    // Only interpolate translation.
    commands.spawn((Transform::default(), TranslationInterpolation));
     
    // Only interpolate rotation.
    commands.spawn((Transform::default(), RotationInterpolation));
     
    // Only interpolate scale.
    commands.spawn((Transform::default(), ScaleInterpolation));
     
    // Interpolate translation and rotation, but not scale.
    commands.spawn((
        Transform::default(),
        TranslationInterpolation,
        RotationInterpolation,
    ));
}

If you want all entities with a Transform to be interpolated by default, you can use TransformInterpolationPlugin::interpolate_all(), or set the interpolate_translation_all, interpolate_rotation_all, and interpolate_scale_all fields.

fn main() {
   App::new()
      .add_plugins(TransformInterpolationPlugin {
          // Interpolate translation and rotation by default, but not scale.
          interpolate_translation_all: true,
          interpolate_rotation_all: true,
          interpolate_scale_all: false,
      })
      // ...
      .run();
}

When interpolation is enabled for all entities by default, you can still opt out of it for individual entities by adding the NoTransformEasing component, or the individual NoTranslationEasing, NoRotationEasing, and NoScaleEasing components.

Note that changing Transform manually in any schedule that doesn’t use a fixed timestep is also supported, but it is equivalent to teleporting, and disables interpolation for the entity for the remainder of that fixed timestep.

§Alternatives

For games where low latency is crucial for gameplay, such as in some first-person shooters or racing games, the small delay introduced by interpolation may be undesirable. In those cases, one option is to use the TransformExtrapolationPlugin instea.

Transform extrapolation predicts future positions based on velocity, and applies easing between the current and predicted Transform. This results in movement that looks smooth and feels responsive, but can stutter when the prediction is incorrect, such as when velocity changes abruptly.

§Easing Backends

By default, transform interpolation uses linear interpolation (lerp) for easing translation and scale, and spherical linear interpolation (slerp) for easing rotation.

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.

Fields§

§interpolate_translation_all: bool

If true, translation will be interpolated for all entities with the Transform component by default.

This can be overridden for individual entities by adding the NoTranslationEasing or NoTransformEasing component.

§interpolate_rotation_all: bool

If true, rotation will be interpolated for all entities with the Transform component by default.

This can be overridden for individual entities by adding the NoRotationEasing or NoTransformEasing component.

§interpolate_scale_all: bool

If true, scale will be interpolated for all entities with the Transform component by default.

This can be overridden for individual entities by adding the NoScaleEasing or NoTransformEasing component.

Implementations§

source§

impl TransformInterpolationPlugin

source

pub const fn interpolate_all() -> Self

Enables interpolation for translation, rotation, and scale for all entities with the Transform component.

This can be overridden for individual entities by adding the NoTransformEasing component, or the individual NoTranslationEasing, NoRotationEasing, and NoScaleEasing components.

Trait Implementations§

source§

impl Debug for TransformInterpolationPlugin

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Default for TransformInterpolationPlugin

source§

fn default() -> TransformInterpolationPlugin

Returns the “default value” for a type. Read more
source§

impl Plugin for TransformInterpolationPlugin

source§

fn build(&self, app: &mut App)

Configures the App to which this plugin is added.
source§

fn finish(&self, app: &mut App)

Finish adding this plugin to the App, once all plugins registered are ready. This can be useful for plugins that depends on another plugin asynchronous setup, like the renderer.
source§

fn ready(&self, _app: &App) -> bool

Has the plugin finished its setup? This can be useful for plugins that need something asynchronous to happen before they can finish their setup, like the initialization of a renderer. Once the plugin is ready, finish should be called.
source§

fn cleanup(&self, _app: &mut App)

Runs after all plugins are built and finished, but before the app schedule is executed. This can be useful if you have some resource that other plugins need during their build step, but after build you want to remove it and send it to another thread.
source§

fn name(&self) -> &str

Configures a name for the Plugin which is primarily used for checking plugin uniqueness and debugging.
source§

fn is_unique(&self) -> bool

If the plugin can be meaningfully instantiated several times in an App, override this method to return false.

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T, U> AsBindGroupShaderType<U> for T
where U: ShaderType, &'a T: for<'a> Into<U>,

source§

fn as_bind_group_shader_type(&self, _images: &RenderAssets<GpuImage>) -> U

Return the T ShaderType for self. When used in AsBindGroup derives, it is safe to assume that all images in self exist.
source§

impl<T> Borrow<T> for T
where T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> Downcast<T> for T

source§

fn downcast(&self) -> &T

source§

impl<T> Downcast for T
where T: Any,

source§

fn into_any(self: Box<T>) -> Box<dyn Any>

Convert Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>. Box<dyn Any> can then be further downcast into Box<ConcreteType> where ConcreteType implements Trait.
source§

fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>

Convert Rc<Trait> (where Trait: Downcast) to Rc<Any>. Rc<Any> can then be further downcast into Rc<ConcreteType> where ConcreteType implements Trait.
source§

fn as_any(&self) -> &(dyn Any + 'static)

Convert &Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &Any’s vtable from &Trait’s.
source§

fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)

Convert &mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &mut Any’s vtable from &mut Trait’s.
source§

impl<T> DowncastSync for T
where T: Any + Send + Sync,

source§

fn into_any_arc(self: Arc<T>) -> Arc<dyn Any + Sync + Send>

Convert Arc<Trait> (where Trait: Downcast) to Arc<Any>. Arc<Any> can then be further downcast into Arc<ConcreteType> where ConcreteType implements Trait.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T> FromWorld for T
where T: Default,

source§

fn from_world(_world: &mut World) -> T

Creates Self using default().

source§

impl<T> Instrument for T

source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T> IntoEither for T

source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

source§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
source§

impl<T> Upcast<T> for T

source§

fn upcast(&self) -> Option<&T>

source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

source§

fn vzip(self) -> V

source§

impl<T> WithSubscriber for T

source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more
source§

impl<T> ConditionalSend for T
where T: Send,

source§

impl<Marker, T> Plugins<Marker> for T
where T: Plugins<Marker>,

source§

impl<T> Settings for T
where T: 'static + Send + Sync,

source§

impl<T> WasmNotSend for T
where T: Send,

source§

impl<T> WasmNotSendSync for T

source§

impl<T> WasmNotSync for T
where T: Sync,