🐦
【Bevy0.13】MaterialMesh2dBundleで生成した図形の色の変更
概要
MaterialMesh2dBundleで生成した図形の色(ColorMaterial)を変更する方法です
STEP1 図形の表示
とりあえず図形を表示してみることから。
BevyのExampleに載っている図形の描画方法そのままです。
use bevy::{prelude::*, sprite::{MaterialMesh2dBundle, Mesh2dHandle}};
#[derive(Component)]
struct Ball;
fn main(){
App::new()
.add_plugins(DefaultPlugins)
.add_systems(Startup, setup)
.run();
}
fn setup(
mut commands : Commands,
mut meshes : ResMut<Assets<Mesh>>,
mut materials : ResMut<Assets<ColorMaterial>>
){
// カメラ生成
commands.spawn(Camera2dBundle::default());
// ボールの生成
commands.spawn((
Ball,
MaterialMesh2dBundle{
mesh : Mesh2dHandle(meshes.add(Circle{radius:30.})),
material : materials.add(Color::GOLD),
..default()
},
));
}
黄色いボールが生成されました。
STEP2 色変更
use bevy::{prelude::*, sprite::{MaterialMesh2dBundle, Mesh2dHandle}};
#[derive(Component)]
struct Ball;
fn main(){
App::new()
.add_plugins(DefaultPlugins)
.add_systems(Startup, setup)
+ .add_systems(Update,change_color)
.run();
}
fn setup(
mut commands : Commands,
mut meshes : ResMut<Assets<Mesh>>,
mut materials : ResMut<Assets<ColorMaterial>>
){
// カメラ生成
commands.spawn(Camera2dBundle::default());
// ボールの生成
commands.spawn((
Ball,
MaterialMesh2dBundle{
mesh : Mesh2dHandle(meshes.add(Circle{radius:30.})),
material : materials.add(Color::GOLD),
..default()
},
));
}
+fn change_color(
+ q_ball : Query<&Handle<ColorMaterial>,With<Ball>>,
+ mut materials : ResMut<Assets<ColorMaterial>>
+){
+ // materialsの中からボールのカラーマテリアルを取得
+ let handle: &Handle<ColorMaterial> = q_ball.single();
+ let colormaterial: &mut ColorMaterial = materials.get_mut(handle.id()).unwrap();
+
+ // 取得したカラーマテリアルの色変更
+ colormaterial.color = Color::SEA_GREEN;
+}
ボールが緑色になりました。
何をやっているかよくわからなかった人への解説
先ほどはボールだけでしたが、今回はボールとボックスの二つを作ってみましょう。
そしてそれぞれのmaterialを共通のものにしてみます。
use bevy::{prelude::*, sprite::{MaterialMesh2dBundle, Mesh2dHandle}};
#[derive(Component)]
struct Ball;
+#[derive(Component)]
+struct Box;
fn main(){
App::new()
.add_plugins(DefaultPlugins)
.add_systems(Startup, setup)
.add_systems(Update,change_color)
.run();
}
fn setup(
mut commands : Commands,
mut meshes : ResMut<Assets<Mesh>>,
mut materials : ResMut<Assets<ColorMaterial>>
){
// カメラ生成
commands.spawn(Camera2dBundle::default());
+ // ボールとボックスに共通のカラーマテリアル
+ let handle_gold : Handle<ColorMaterial> = materials.add(Color::GOLD);
// ボールの生成
commands.spawn((
Ball,
MaterialMesh2dBundle{
mesh : Mesh2dHandle(meshes.add(Circle{radius:30.})),
+ material : handle_gold.clone(),
+ transform: Transform::from_xyz(-100., 0., 0.),
..default()
},
));
+ // ボックスの生成
+ commands.spawn((
+ Box,
+ MaterialMesh2dBundle{
+ mesh : Mesh2dHandle(meshes.add(Rectangle{half_size: Vec2::new(20., 20.)})),
- material : materials.add(Color::GOLD),
+ material : handle_gold.clone(),
+ transform: Transform::from_xyz(100., 0., 0.),
+ ..default()
+ },
+ ));
+}
fn change_color(
q_ball : Query<&Handle<ColorMaterial>,With<Ball>>,
mut materials : ResMut<Assets<ColorMaterial>>
){
// materialsの中からボールのカラーマテリアルを取得
let handle: &Handle<ColorMaterial> = q_ball.single();
let colormaterial: &mut ColorMaterial = materials.get_mut(handle.id()).unwrap();
// カラーマテリアルの色変更
colormaterial.color = Color::SEA_GREEN;
}
change_color関数はボールのカラーマテリアルの色のみを変更したように見えますが、結果を見るとボックスの色も変更されています。これはsetup関数内で図形を生成したとき、ボールとボックスそれぞれに共通のカラーマテリアルを設定しているからです。
materials.add()の戻り値であるHandle<ColorMaterial>とやらはmaterials配列に追加したColorMaterialへのインデックスです。つまり図形に対して色を直接指定しているわけではなく、materials配列に色を格納し、その色へのインデックスを指定しているということです。
色を変えたいときはそのインデックスを元にmaterialsからカラーマテリアルを取得して、その色を変更しているわけです。それがchange_color関数内の処理です。
Discussion