pub enum RigidBody {
Dynamic,
Static,
Kinematic,
}
Expand description
A non-deformable body used for the simulation of most physics objects.
§Rigid Body Types
A rigid body can be either dynamic, kinematic or static.
- Dynamic bodies are similar to real life objects and are affected by forces and contacts.
- Kinematic bodies can only be moved programmatically, which is useful for things like character controllers and moving platforms.
- Static bodies can not move, so they can be good for objects in the environment like the ground and walls.
§Creation
Creating a rigid body is as simple as adding the RigidBody
component,
and an optional Collider
:
use avian3d::prelude::*;
use bevy::prelude::*;
fn setup(mut commands: Commands) {
// Spawn a dynamic rigid body and specify its position.
commands.spawn((
RigidBody::Dynamic,
Collider::capsule(0.5, 1.5),
Transform::from_xyz(0.0, 3.0, 0.0),
));
}
By default, dynamic rigid bodies will have mass properties computed based on the attached colliders
and their ColliderDensity
. See the Mass properties section for more information.
§Movement
A rigid body can be moved in three ways: by modifying its position directly, by changing its velocity, or by applying forces or impulses.
To change the position of a rigid body, you can simply modify its Transform
:
use avian3d::prelude::*;
use bevy::prelude::*;
fn move_bodies(mut query: Query<&mut Transform, With<RigidBody>>) {
for mut transform in query.iter_mut() {
transform.translation.x += 0.1;
}
}
However, moving a dynamic body by changing its position directly is similar to teleporting the body, which can result in unexpected behavior since the body can move inside walls.
You can instead change the velocity of a dynamic or kinematic body with the LinearVelocity
and AngularVelocity
components:
use avian3d::prelude::*;
use bevy::prelude::*;
fn accelerate_bodies(mut query: Query<(&mut LinearVelocity, &mut AngularVelocity)>) {
for (mut linear_velocity, mut angular_velocity) in query.iter_mut() {
linear_velocity.x += 0.05;
angular_velocity.z += 0.05;
}
}
For applying forces and impulses to dynamic bodies, see the ExternalForce
, ExternalTorque
,
ExternalImpulse
and ExternalAngularImpulse
components.
Avian does not have a built-in character controller, so if you need one,
you will need to implement it yourself or use a third party option.
You can take a look at the basic_dynamic_character
and basic_kinematic_character
examples for a simple implementation.
§Mass Properties
Every dynamic rigid body has mass, angular inertia, and a center of mass. These mass properties determine how the rigid body responds to forces and torques.
- Mass: Represents resistance to linear acceleration. A higher mass requires more force for the same acceleration.
- Angular Inertia: Represents resistance to angular acceleration. A higher angular inertia requires more torque for the same angular acceleration.
- Center of Mass: The average position of mass in the body. Applying forces at this point produces no torque.
Static and kinematic rigid bodies have infinite mass and angular inertia, and do not respond to forces or torques. Zero mass for a dynamic body is also treated as a special case, and corresponds to infinite mass.
If no mass properties are set, they are computed automatically from attached colliders based on their shape and density.
// Note: `ColliderDensity` is optional, and defaults to `1.0` if not present.
commands.spawn((
RigidBody::Dynamic,
Collider::capsule(0.5, 1.5),
ColliderDensity(2.0),
));
If mass properties are set with the Mass
, AngularInertia
, and CenterOfMass
components,
they override the values computed from colliders.
// Override mass and the center of mass, but use the collider's angular inertia.
commands.spawn((
RigidBody::Dynamic,
Collider::capsule(0.5, 1.5),
Mass(5.0),
CenterOfMass::new(0.0, -0.5, 0.0),
));
If the rigid body has child colliders, their mass properties will be combined for
the total ComputedMass
, ComputedAngularInertia
, and ComputedCenterOfMass
.
// Total mass: 10.0 + 5.0 = 15.0
// Total center of mass: (10.0 * [0.0, -0.5, 0.0] + 5.0 * [0.0, 4.0, 0.0]) / (10.0 + 5.0) = [0.0, 1.0, 0.0]
commands.spawn((
RigidBody::Dynamic,
Collider::capsule(0.5, 1.5),
Mass(10.0),
CenterOfMass::new(0.0, -0.5, 0.0),
Transform::default(),
))
.with_child((
Collider::sphere(1.0),
Mass(5.0),
Transform::from_xyz(0.0, 4.0, 0.0),
));
To prevent child entities from contributing to the total mass properties, use the NoAutoMass
,
NoAutoAngularInertia
, and NoAutoCenterOfMass
marker components.
// Total mass: 10.0
// Total center of mass: [0.0, -0.5, 0.0]
commands.spawn((
RigidBody::Dynamic,
Collider::capsule(0.5, 1.5),
Mass(10.0),
CenterOfMass::new(0.0, -0.5, 0.0),
NoAutoMass,
NoAutoCenterOfMass,
Transform::default(),
))
.with_child((
Collider::sphere(1.0),
Mass(5.0),
Transform::from_xyz(0.0, 4.0, 0.0),
));
See the mass_properties
module for more information.
§See More
- Colliders
- Gravity and gravity scale
- Linear and angular velocity damping
- Friction and restitution (bounciness)
- Lock translational and rotational axes
- Dominance
- Continuous Collision Detection
Transform
interpolation and extrapolation- Temporarily disabling a rigid body
- Automatic deactivation with sleeping
Variants§
Dynamic
Dynamic bodies are bodies that are affected by forces, velocity and collisions.
Static
Static bodies are not affected by any forces, collisions or velocity, and they act as if they have an infinite mass and moment of inertia. The only way to move a static body is to manually change its position.
Collisions with static bodies will affect dynamic bodies, but not other static bodies or kinematic bodies.
Static bodies are typically used for things like the ground, walls and any other objects that you don’t want to move.
Kinematic
Kinematic bodies are bodies that are not affected by any external forces or collisions. They will realistically affect colliding dynamic bodies, but not other kinematic bodies.
Unlike static bodies, kinematic bodies can have velocity. The engine doesn’t modify the values of a kinematic body’s components, so you have full control of them.
Implementations§
Trait Implementations§
source§impl Component for RigidBody
impl Component for RigidBody
Required Components: LinearVelocity
, AngularVelocity
, ExternalForce
, ExternalTorque
, ExternalImpulse
, ExternalAngularImpulse
, ComputedMass
, ComputedAngularInertia
, ComputedCenterOfMass
, AccumulatedTranslation
, PreSolveAccumulatedTranslation
, [PreSolveLinearVelocity
], [PreSolveAngularVelocity
], PreSolveRotation
, PreviousRotation
, GlobalAngularInertia
.
A component’s Required Components are inserted whenever it is inserted. Note that this will also insert the required components of the required components, recursively, in depth-first order.
source§const STORAGE_TYPE: StorageType = bevy::ecs::component::StorageType::Table
const STORAGE_TYPE: StorageType = bevy::ecs::component::StorageType::Table
source§fn register_required_components(
requiree: ComponentId,
components: &mut Components,
storages: &mut Storages,
required_components: &mut RequiredComponents,
inheritance_depth: u16,
)
fn register_required_components( requiree: ComponentId, components: &mut Components, storages: &mut Storages, required_components: &mut RequiredComponents, inheritance_depth: u16, )
source§fn register_component_hooks(hooks: &mut ComponentHooks)
fn register_component_hooks(hooks: &mut ComponentHooks)
ComponentHooks
.source§impl Enum for RigidBody
impl Enum for RigidBody
source§fn field(&self, __name_param: &str) -> Option<&dyn PartialReflect>
fn field(&self, __name_param: &str) -> Option<&dyn PartialReflect>
source§fn field_at(&self, __index_param: usize) -> Option<&dyn PartialReflect>
fn field_at(&self, __index_param: usize) -> Option<&dyn PartialReflect>
source§fn field_mut(&mut self, __name_param: &str) -> Option<&mut dyn PartialReflect>
fn field_mut(&mut self, __name_param: &str) -> Option<&mut dyn PartialReflect>
source§fn field_at_mut(
&mut self,
__index_param: usize,
) -> Option<&mut dyn PartialReflect>
fn field_at_mut( &mut self, __index_param: usize, ) -> Option<&mut dyn PartialReflect>
source§fn index_of(&self, __name_param: &str) -> Option<usize>
fn index_of(&self, __name_param: &str) -> Option<usize>
source§fn name_at(&self, __index_param: usize) -> Option<&str>
fn name_at(&self, __index_param: usize) -> Option<&str>
source§fn iter_fields(&self) -> VariantFieldIter<'_>
fn iter_fields(&self) -> VariantFieldIter<'_>
source§fn variant_name(&self) -> &str
fn variant_name(&self) -> &str
source§fn variant_index(&self) -> usize
fn variant_index(&self) -> usize
source§fn variant_type(&self) -> VariantType
fn variant_type(&self) -> VariantType
fn clone_dynamic(&self) -> DynamicEnum
source§fn is_variant(&self, variant_type: VariantType) -> bool
fn is_variant(&self, variant_type: VariantType) -> bool
source§fn variant_path(&self) -> String
fn variant_path(&self) -> String
source§impl FromReflect for RigidBody
impl FromReflect for RigidBody
source§fn from_reflect(__param0: &dyn PartialReflect) -> Option<Self>
fn from_reflect(__param0: &dyn PartialReflect) -> Option<Self>
Self
from a reflected value.source§fn take_from_reflect(
reflect: Box<dyn PartialReflect>,
) -> Result<Self, Box<dyn PartialReflect>>
fn take_from_reflect( reflect: Box<dyn PartialReflect>, ) -> Result<Self, Box<dyn PartialReflect>>
Self
using,
constructing the value using from_reflect
if that fails. Read moresource§impl GetTypeRegistration for RigidBody
impl GetTypeRegistration for RigidBody
source§fn get_type_registration() -> TypeRegistration
fn get_type_registration() -> TypeRegistration
TypeRegistration
for this type.source§fn register_type_dependencies(registry: &mut TypeRegistry)
fn register_type_dependencies(registry: &mut TypeRegistry)
source§impl PartialReflect for RigidBody
impl PartialReflect for RigidBody
source§fn get_represented_type_info(&self) -> Option<&'static TypeInfo>
fn get_represented_type_info(&self) -> Option<&'static TypeInfo>
source§fn clone_value(&self) -> Box<dyn PartialReflect>
fn clone_value(&self) -> Box<dyn PartialReflect>
Reflect
trait object. Read moresource§fn try_apply(
&mut self,
__value_param: &dyn PartialReflect,
) -> Result<(), ApplyError>
fn try_apply( &mut self, __value_param: &dyn PartialReflect, ) -> Result<(), ApplyError>
source§fn reflect_kind(&self) -> ReflectKind
fn reflect_kind(&self) -> ReflectKind
source§fn reflect_ref(&self) -> ReflectRef<'_>
fn reflect_ref(&self) -> ReflectRef<'_>
source§fn reflect_mut(&mut self) -> ReflectMut<'_>
fn reflect_mut(&mut self) -> ReflectMut<'_>
source§fn reflect_owned(self: Box<Self>) -> ReflectOwned
fn reflect_owned(self: Box<Self>) -> ReflectOwned
source§fn try_into_reflect(
self: Box<Self>,
) -> Result<Box<dyn Reflect>, Box<dyn PartialReflect>>
fn try_into_reflect( self: Box<Self>, ) -> Result<Box<dyn Reflect>, Box<dyn PartialReflect>>
source§fn try_as_reflect(&self) -> Option<&dyn Reflect>
fn try_as_reflect(&self) -> Option<&dyn Reflect>
source§fn try_as_reflect_mut(&mut self) -> Option<&mut dyn Reflect>
fn try_as_reflect_mut(&mut self) -> Option<&mut dyn Reflect>
source§fn into_partial_reflect(self: Box<Self>) -> Box<dyn PartialReflect>
fn into_partial_reflect(self: Box<Self>) -> Box<dyn PartialReflect>
source§fn as_partial_reflect(&self) -> &dyn PartialReflect
fn as_partial_reflect(&self) -> &dyn PartialReflect
source§fn as_partial_reflect_mut(&mut self) -> &mut dyn PartialReflect
fn as_partial_reflect_mut(&mut self) -> &mut dyn PartialReflect
source§fn reflect_hash(&self) -> Option<u64>
fn reflect_hash(&self) -> Option<u64>
source§fn reflect_partial_eq(&self, value: &dyn PartialReflect) -> Option<bool>
fn reflect_partial_eq(&self, value: &dyn PartialReflect) -> Option<bool>
source§fn apply(&mut self, value: &(dyn PartialReflect + 'static))
fn apply(&mut self, value: &(dyn PartialReflect + 'static))
source§fn serializable(&self) -> Option<Serializable<'_>>
fn serializable(&self) -> Option<Serializable<'_>>
source§fn is_dynamic(&self) -> bool
fn is_dynamic(&self) -> bool
source§impl Reflect for RigidBody
impl Reflect for RigidBody
source§fn as_any_mut(&mut self) -> &mut dyn Any
fn as_any_mut(&mut self) -> &mut dyn Any
&mut dyn Any
. Read moresource§fn into_reflect(self: Box<Self>) -> Box<dyn Reflect>
fn into_reflect(self: Box<Self>) -> Box<dyn Reflect>
source§fn as_reflect(&self) -> &dyn Reflect
fn as_reflect(&self) -> &dyn Reflect
source§fn as_reflect_mut(&mut self) -> &mut dyn Reflect
fn as_reflect_mut(&mut self) -> &mut dyn Reflect
source§impl TypePath for RigidBody
impl TypePath for RigidBody
source§fn type_path() -> &'static str
fn type_path() -> &'static str
source§fn short_type_path() -> &'static str
fn short_type_path() -> &'static str
source§fn type_ident() -> Option<&'static str>
fn type_ident() -> Option<&'static str>
source§fn crate_name() -> Option<&'static str>
fn crate_name() -> Option<&'static str>
impl Copy for RigidBody
impl Eq for RigidBody
impl StructuralPartialEq for RigidBody
Auto Trait Implementations§
impl Freeze for RigidBody
impl RefUnwindSafe for RigidBody
impl Send for RigidBody
impl Sync for RigidBody
impl Unpin for RigidBody
impl UnwindSafe for RigidBody
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<C> Bundle for Cwhere
C: Component,
impl<C> Bundle for Cwhere
C: Component,
fn component_ids( components: &mut Components, storages: &mut Storages, ids: &mut impl FnMut(ComponentId), )
unsafe fn from_components<T, F>(ctx: &mut T, func: &mut F) -> C
source§fn register_required_components(
components: &mut Components,
storages: &mut Storages,
required_components: &mut RequiredComponents,
)
fn register_required_components( components: &mut Components, storages: &mut Storages, required_components: &mut RequiredComponents, )
Bundle
.source§fn get_component_ids(
components: &Components,
ids: &mut impl FnMut(Option<ComponentId>),
)
fn get_component_ids( components: &Components, ids: &mut impl FnMut(Option<ComponentId>), )
source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
source§unsafe fn clone_to_uninit(&self, dst: *mut T)
unsafe fn clone_to_uninit(&self, dst: *mut T)
clone_to_uninit
)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>
. 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>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
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)
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> DowncastSync for T
impl<T> DowncastSync for T
source§impl<C> DynamicBundle for Cwhere
C: Component,
impl<C> DynamicBundle for Cwhere
C: Component,
fn get_components(self, func: &mut impl FnMut(StorageType, OwningPtr<'_>))
source§impl<T> DynamicTypePath for Twhere
T: TypePath,
impl<T> DynamicTypePath for Twhere
T: TypePath,
source§fn reflect_type_path(&self) -> &str
fn reflect_type_path(&self) -> &str
TypePath::type_path
.source§fn reflect_short_type_path(&self) -> &str
fn reflect_short_type_path(&self) -> &str
source§fn reflect_type_ident(&self) -> Option<&str>
fn reflect_type_ident(&self) -> Option<&str>
TypePath::type_ident
.source§fn reflect_crate_name(&self) -> Option<&str>
fn reflect_crate_name(&self) -> Option<&str>
TypePath::crate_name
.source§fn reflect_module_path(&self) -> Option<&str>
fn reflect_module_path(&self) -> Option<&str>
source§impl<T> DynamicTyped for Twhere
T: Typed,
impl<T> DynamicTyped for Twhere
T: Typed,
source§fn reflect_type_info(&self) -> &'static TypeInfo
fn reflect_type_info(&self) -> &'static TypeInfo
Typed::type_info
.source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
source§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
key
and return true
if they are equal.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> GetPath for T
impl<T> GetPath for T
source§fn reflect_path<'p>(
&self,
path: impl ReflectPath<'p>,
) -> Result<&(dyn PartialReflect + 'static), ReflectPathError<'p>>
fn reflect_path<'p>( &self, path: impl ReflectPath<'p>, ) -> Result<&(dyn PartialReflect + 'static), ReflectPathError<'p>>
path
. Read moresource§fn reflect_path_mut<'p>(
&mut self,
path: impl ReflectPath<'p>,
) -> Result<&mut (dyn PartialReflect + 'static), ReflectPathError<'p>>
fn reflect_path_mut<'p>( &mut self, path: impl ReflectPath<'p>, ) -> Result<&mut (dyn PartialReflect + 'static), ReflectPathError<'p>>
path
. Read moresource§fn path<'p, T>(
&self,
path: impl ReflectPath<'p>,
) -> Result<&T, ReflectPathError<'p>>where
T: Reflect,
fn path<'p, T>(
&self,
path: impl ReflectPath<'p>,
) -> Result<&T, ReflectPathError<'p>>where
T: Reflect,
path
. Read moresource§fn path_mut<'p, T>(
&mut self,
path: impl ReflectPath<'p>,
) -> Result<&mut T, ReflectPathError<'p>>where
T: Reflect,
fn path_mut<'p, T>(
&mut self,
path: impl ReflectPath<'p>,
) -> Result<&mut T, ReflectPathError<'p>>where
T: Reflect,
path
. Read moresource§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 moresource§impl<T> Pointable for T
impl<T> Pointable for T
source§impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
source§fn to_subset(&self) -> Option<SS>
fn to_subset(&self) -> Option<SS>
self
from the equivalent element of its
superset. Read moresource§fn is_in_subset(&self) -> bool
fn is_in_subset(&self) -> bool
self
is actually part of its subset T
(and can be converted to it).source§fn to_subset_unchecked(&self) -> SS
fn to_subset_unchecked(&self) -> SS
self.to_subset
but without any property checks. Always succeeds.source§fn from_subset(element: &SS) -> SP
fn from_subset(element: &SS) -> SP
self
to the equivalent element of its superset.