pub unsafe trait Bundle: DynamicBundle + Send + Sync + 'static { }
Expand description
The Bundle
trait enables insertion and removal of Component
s from an entity.
Implementors of the Bundle
trait are called ‘bundles’.
Each bundle represents a static set of Component
types.
Currently, bundles can only contain one of each Component
, and will
panic once initialised if this is not met.
Insertion
The primary use for bundles is to add a useful collection of components to an entity.
Adding a value of bundle to an entity will add the components from the set it represents to the entity. The values of these components are taken from the bundle. If an entity already had one of these components, the entity’s original component value will be overwritten.
Importantly, bundles are only their constituent set of components.
You should not use bundles as a unit of behavior.
The behavior of your app can only be considered in terms of components, as systems,
which drive the behavior of a bevy
application, operate on combinations of
components.
This rule is also important because multiple bundles may contain the same component type,
calculated in different ways — adding both of these bundles to one entity
would create incoherent behavior.
This would be unexpected if bundles were treated as an abstraction boundary, as
the abstraction would be unmaintainable for these cases.
For example, both Camera3dBundle
and Camera2dBundle
contain the CameraRenderGraph
component, but specifying different render graphs to use.
If the bundles were both added to the same entity, only one of these two bundles would work.
For this reason, there is intentionally no Query
to match whether an entity
contains the components of a bundle.
Queries should instead only select the components they logically operate on.
Removal
Bundles are also used when removing components from an entity.
Removing a bundle from an entity will remove any of its components attached to the entity from the entity. That is, if the entity does not have all the components of the bundle, those which are present will be removed.
Implementors
Every type which implements Component
also implements Bundle
, since
Component
types can be added to or removed from an entity.
Additionally, Tuples of bundles are also Bundle
(with up to 15 bundles).
These bundles contain the items of the ‘inner’ bundles.
This is a convenient shorthand which is primarily used when spawning entities.
For example, spawning an entity using the bundle (SpriteBundle {...}, PlayerMarker)
will spawn an entity with components required for a 2d sprite, and the PlayerMarker
component.
unit
, otherwise known as ()
, is a Bundle
containing no components (since it
can also be considered as the empty tuple).
This can be useful for spawning large numbers of empty entities using
World::spawn_batch
.
Tuple bundles can be nested, which can be used to create an anonymous bundle with more than
15 items.
However, in most cases where this is required, the derive macro Bundle
should be
used instead.
The derived Bundle
implementation contains the items of its fields, which all must
implement Bundle
.
As explained above, this includes any Component
type, and other derived bundles.
If you want to add PhantomData
to your Bundle
you have to mark it with #[bundle(ignore)]
.
use bevy_ecs::{component::Component, bundle::Bundle};
#[derive(Component)]
struct XPosition(i32);
#[derive(Component)]
struct YPosition(i32);
#[derive(Bundle)]
struct PositionBundle {
// A bundle can contain components
x: XPosition,
y: YPosition,
}
// You have to implement `Default` for ignored field types in bundle structs.
#[derive(Default)]
struct Other(f32);
#[derive(Bundle)]
struct NamedPointBundle<T: Send + Sync + 'static> {
// Or other bundles
a: PositionBundle,
// In addition to more components
z: PointName,
// when you need to use `PhantomData` you have to mark it as ignored
#[bundle(ignore)]
_phantom_data: PhantomData<T>
}
#[derive(Component)]
struct PointName(String);
Safety
Manual implementations of this trait are unsupported.
That is, there is no safe way to implement this trait, and you must not do so.
If you want a type to implement Bundle
, you must use derive@Bundle
.