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: boolIf 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: boolIf 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: boolIf 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
impl TransformInterpolationPlugin
Sourcepub const fn interpolate_all() -> Self
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
impl Debug for TransformInterpolationPlugin
Source§impl Default for TransformInterpolationPlugin
impl Default for TransformInterpolationPlugin
Source§fn default() -> TransformInterpolationPlugin
fn default() -> TransformInterpolationPlugin
Source§impl Plugin for TransformInterpolationPlugin
impl Plugin for TransformInterpolationPlugin
Source§fn finish(&self, app: &mut App)
fn finish(&self, app: &mut App)
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
fn ready(&self, _app: &App) -> bool
finish should be called.Source§fn cleanup(&self, _app: &mut App)
fn cleanup(&self, _app: &mut App)
Auto Trait Implementations§
impl Freeze for TransformInterpolationPlugin
impl RefUnwindSafe for TransformInterpolationPlugin
impl Send for TransformInterpolationPlugin
impl Sync for TransformInterpolationPlugin
impl Unpin for TransformInterpolationPlugin
impl UnwindSafe for TransformInterpolationPlugin
Blanket Implementations§
Source§impl<T, U> AsBindGroupShaderType<U> for T
impl<T, U> AsBindGroupShaderType<U> for T
Source§fn as_bind_group_shader_type(&self, _images: &RenderAssets<GpuImage>) -> U
fn as_bind_group_shader_type(&self, _images: &RenderAssets<GpuImage>) -> U
T ShaderType for self. When used in AsBindGroup
derives, it is safe to assume that all images in self exist.Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
Source§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>, which can then be
downcast into Box<dyn ConcreteType> where ConcreteType implements Trait.Source§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait> (where Trait: Downcast) to Rc<Any>, which can then be further
downcast into Rc<ConcreteType> where ConcreteType implements Trait.Source§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&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)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&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> DowncastSend for T
impl<T> DowncastSend for T
Source§impl<T> DowncastSync for T
impl<T> DowncastSync for T
Source§impl<T> FromWorld for Twhere
T: Default,
impl<T> FromWorld for Twhere
T: Default,
Source§fn from_world(_world: &mut World) -> T
fn from_world(_world: &mut World) -> T
Creates Self using default().
Source§impl<T, W> HasTypeWitness<W> for Twhere
W: MakeTypeWitness<Arg = T>,
T: ?Sized,
impl<T, W> HasTypeWitness<W> for Twhere
W: MakeTypeWitness<Arg = T>,
T: ?Sized,
Source§impl<T> Identity for Twhere
T: ?Sized,
impl<T> Identity for Twhere
T: ?Sized,
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
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 moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
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