I'm facing a problem where an entity already exists, but I want to add a PbrBundle to it. To try solve this I'm attempting to spawn a child entity along with the PbrBundle. Hoping that it will be transformed according to the parent, but the transformation part doesn't seem to work out.
fn spawn_parent(commands: &mut Commands) -> Entity {
let entity = commands.spawn((Transform::from_translation(vec3(1.0, 0.0, 0.0)),)) ...
I'm expecting the line drawn by the code to not sit in the middle of the screen (should be translated to the right, changing the parent's doesn't seem to have any effect at all):
I get the following output from the code below:
Spawned camera: 0v0
Spawned parent: 1v0
Spawned child: 2v0
0v0 changed global transform: Vec3(0.0, 0.0, 10.0)
2v0 changed parent: Parent(1v0)
1v0 changed children: Children([2v0])
2v0 changed global transform: Vec3(0.0, 0.0, 0.0)
The code:
use bevy::prelude::*;
use bevy::math::vec3;
use bevy::render::mesh::Indices;
use bevy::render::pipeline::PrimitiveTopology;
fn main() {
App::build()
.add_plugins(DefaultPlugins)
.add_system(debug_global_transform.system())
.add_system(debug_children.system())
.add_system(debug_parent.system())
.add_startup_system(setup.system())
.run();
}
fn setup(commands: &mut Commands, meshes: ResMut<Assets<Mesh>>, materials: ResMut<Assets<StandardMaterial>>) {
spawn_camera(commands);
let parent_entity = spawn_parent(commands);
spawn_child(commands, meshes, materials, parent_entity);
}
fn spawn_camera(commands: &mut Commands) {
commands.spawn(Camera3dBundle {
perspective_projection: Default::default(),
transform: Transform::from_translation(Vec3::new(0.0, 0.0, 10.0))
.looking_at(Vec3::zero(), Vec3::unit_y()),
..Default::default()
});
println!("Spawned camera: {:?}", commands.current_entity().unwrap());
}
fn spawn_parent(commands: &mut Commands) -> Entity {
let entity = commands.spawn((Transform::from_translation(vec3(1.0, 0.0, 0.0)),)).current_entity().unwrap();
println!("Spawned parent: {:?}", entity);
entity
}
fn spawn_child(commands: &mut Commands, mut meshes: ResMut<Assets<Mesh>>, mut materials: ResMut<Assets<StandardMaterial>>, parent_entity: Entity) {
let mut mesh = Mesh::new(PrimitiveTopology::LineList);
mesh.set_attribute(Mesh::ATTRIBUTE_POSITION, vec![[0.0, 0.0, 0.0], [0.0, 1.0, 0.0]]);
mesh.set_attribute(Mesh::ATTRIBUTE_NORMAL, vec![[0.0, 0.0, 0.0], [0.0, 0.0, 0.0]]);
mesh.set_attribute(Mesh::ATTRIBUTE_UV_0, vec![[0.0, 0.0, 0.0], [0.0, 0.0, 0.0]]);
mesh.set_indices(Some(Indices::U32(vec![0, 1])));
let child_entity = commands.spawn(PbrBundle {
mesh: meshes.add(mesh),
material: materials.add(Color::rgb(1.0, 1.0, 1.0).into()),
// Default transform, let the parent decide where this is drawn
..Default::default()
})
//.with(Parent(parent_entity)) // Doesn't seem to work well either
.current_entity()
.unwrap();
println!("Spawned child: {:?}", child_entity);
commands.push_children(parent_entity, &[child_entity]);
}
fn debug_global_transform(query: Query<(Entity, &GlobalTransform), Changed<GlobalTransform>>) {
query.iter()
.for_each(|(entity, transform)| {
println!("{:?} changed global transform: {:?}", entity, transform.translation);
});
}
fn debug_children(children_query: Query<(Entity, &Children), Changed<Children>>) {
for (entity, children) in children_query.iter() {
println!("{:?} changed children: {:?}", entity, children);
}
}
fn debug_parent(parent_query: Query<(Entity, &Parent), Changed<Parent>>) {
for (entity, parent) in parent_query.iter() {
println!("{:?} changed parent: {:?}", entity, parent);
}
}