This crate lets you map a complex entity tree onto a single component as long as those entities (and their ancestors) are named.
This is especially useful for scenes spawned from GLTF models since you'd need complex queries to retrieve deep entities from the scene hierarchy.
This repository is using cargo-make
, it will take care of installing all
required cargo extensions and rustup components used in this repository.
- Run
scripts/setup.sh
(Or runcargo install cargo-make
) - (Optional) Install the rest of the tooling/cargo extensions using
cargo make setup
cargo make all
to run everything that could make ci fail (Everything below)cargo make build
to build all cratescargo make test
to test all cratescargo make format
to format all cratescargo make lint
to lint all crates usingclippy
andrustfmt
cargo make book-build
to build the documentation book
Running the example:
cargo run -p bevy_descendant_collector --example turret
Imagine you have a model file with the following structure in Blender:
Collection
├── Armature
│ ├── Bone.Root
│ │ └── Bone.Neck
│ │ └── Bone.Head
│ └── Bone.Head.IK_CTRL
You can define a component like this:
#[derive(Component, EntityCollectorTarget)]
#[name_path("Armature")]
pub struct MyTurretArmature {
#[name_path("Bone.Root")]
pub base: Entity,
#[name_path("Bone.Root", "Bone.Neck")]
pub neck: Entity,
#[name_path("Bone.Root", "Bone.Neck", "Bone.Head")]
pub head: Entity,
#[name_path("Bone.Head.IK_CTRL")]
pub head_ik_ctrl: Entity,
}
Then, you need to add a Plugin, this plugin will handle the insertion of this component:
Each different
EntityCollectorTarget
needs its own plugin added!
In this example this is a GLTF model, so I want the root entity to be resolved
as a scene. HierarchyRootPosition::Scene
tells the plugin to find the root
of the hierarchy based on #[name_path("Armature")]
among the grandchildren
of the entity where I want this MyTurretArmature
to be inserted into.
app.add_plugins(DescendantCollectorPlugin::<MyTurretArmature>::new(HierarchyRootPosition::Scene));
And lastly, I need to identify the entities where I want MyTurretArmature
to
be inserted into! To do this, when you spawn this scene, add the target
component to your entity.
fn spawn_turret(mut commands: Commands, turret_model_assets: Res<TurretModelAssets>) {
commands.spawn((
SceneBundle {
scene: turret_model_assets.turret_model.clone(),
..default()
},
DescendantCollectorTarget::<MyTurretArmature>::default(),
));
}
In case you want to inspect the output of the proc macro.
If you haven't installed cargo-expand
yet.
cargo install cargo-expand
cargo expand --example turret
Bevy | bevy_descendant_collector |
---|---|
0.14 | 0.2 |
0.13 | 0.1 |