How to swap color materials in an update call?

31 Views Asked by At

During bevy setup, I've spawned multiple rectangles with two different colors. How do I update these rectangles with a new color material?

// in setup
commands.spawn(
    (MaterialMesh2dBundle {
        mesh: Mesh2dHandle(meshes.add(Rectangle::new(10., 10.))),
        material: if dull_world.is_live(row_index, col_index) {
            materials.add(Color::PURPLE)
        } else {
            materials.add(Color::GREEN)
        },
        transform: Transform::from_xyz(
            (row_index as f32 - row_len as f32 / 2.) * 10.,
            (col_index as f32 - col_len as f32 / 2.) * 10.,
            0.0,
        ),
        ..default()
    }),
);

full code

1

There are 1 best solutions below

0
kemicofa ghost On BEST ANSWER

One way to accomplish this is to reuse the material handles you're creating by inserting them as Resources.

Then during your update call, query the entities that match Query<&mut Handle<ColorMaterial>> with the resource you want Res<CellDeadColor>. Since the handles exist already, you simply need to clone them and apply them to the color material handler.

// global
#[derive(Resource)]
struct CellDeadColor(Handle<ColorMaterial>);

#[derive(Resource)]
struct CellLiveColor(Handle<ColorMaterial>);

// setup
let live_color_handle = materials.add(Color::GREEN); // Handle<ColorMaterial>
let dead_color_handle = materials.add(Color::PURPLE); // Handle<ColorMaterial>

let cell_live_color = CellLiveColor(live_color_handle.clone());
let cell_dead_color = CellDeadColor(dead_color_handle.clone());

commands.insert_resource(cell_live_color);
commands.insert_resource(cell_dead_color);

commands.spawn(
    (MaterialMesh2dBundle {
        mesh: Mesh2dHandle(meshes.add(Rectangle::new(10., 10.))),
        material: if dull_world.is_live(row_index, col_index) {
            live_color_handle.clone()
        } else {
            dead_color_handle.clone()
        },
        transform: Transform::from_xyz(
            (row_index as f32 - row_len as f32 / 2.) * 10.,
            (col_index as f32 - col_len as f32 / 2.) * 10.,
            0.0,
        ),
        ..default()
    }),
);

// update
fn render_world(
    mut q_entities: Query<(&mut Handle<ColorMaterial>, &Cell)>,
    q_dull_world: Query<&DullWorld>,
    q_dead_cell_color: Res<CellDeadColor>,
    q_live_cell_color: Res<CellLiveColor>,
) {
    let dull_world = q_dull_world.iter().next().unwrap();
    for (mut entity, cell) in q_entities.iter_mut() {
        if dull_world.is_live(cell.row_index, cell.col_index) {
            *entity = q_dead_cell_color.0.clone();
        } else {
            *entity = q_live_cell_color.0.clone();
        };
    }
}