edit_material_on_gltf/
edit_material_on_gltf.rs1use bevy::{
4 audio::AudioPlugin, color::palettes, gltf::GltfMaterialName, prelude::*,
5 scene::SceneInstanceReady,
6};
7
8fn main() {
9 App::new()
10 .add_plugins(DefaultPlugins.build().disable::<AudioPlugin>())
11 .add_systems(Startup, setup_scene)
12 .add_observer(change_material)
13 .run();
14}
15
16#[derive(Component)]
19struct ColorOverride(Color);
20
21fn setup_scene(mut commands: Commands, asset_server: Res<AssetServer>) {
22 commands.spawn((
23 Camera3d::default(),
24 Transform::from_xyz(0., 1., 2.5).looking_at(Vec3::new(0., 0.25, 0.), Dir3::Y),
25 ));
26
27 commands.spawn((
28 DirectionalLight::default(),
29 Transform::from_xyz(0., 1., 0.25).looking_at(Vec3::ZERO, Dir3::Y),
30 ));
31
32 let flight_helmet = asset_server
34 .load(GltfAssetLabel::Scene(0).from_asset("models/FlightHelmet/FlightHelmet.gltf"));
35 commands.spawn(SceneRoot(flight_helmet.clone()));
37 commands.spawn((
39 SceneRoot(flight_helmet.clone()),
40 Transform::from_xyz(-1.25, 0., 0.),
41 ColorOverride(palettes::tailwind::RED_300.into()),
42 ));
43 commands.spawn((
45 SceneRoot(flight_helmet),
46 Transform::from_xyz(1.25, 0., 0.),
47 ColorOverride(palettes::tailwind::GREEN_300.into()),
48 ));
49}
50
51fn change_material(
52 scene_ready: On<SceneInstanceReady>,
53 mut commands: Commands,
54 children: Query<&Children>,
55 color_override: Query<&ColorOverride>,
56 mesh_materials: Query<(&MeshMaterial3d<StandardMaterial>, &GltfMaterialName)>,
57 mut asset_materials: ResMut<Assets<StandardMaterial>>,
58) {
59 info!("processing Scene Entity: {}", scene_ready.entity);
60 for descendant in children.iter_descendants(scene_ready.entity) {
62 let Ok((id, material_name)) = mesh_materials.get(descendant) else {
64 continue;
65 };
66 let Some(material) = asset_materials.get_mut(id.id()) else {
68 continue;
69 };
70
71 match material_name.0.as_str() {
73 "LeatherPartsMat" => {
74 info!("editing LeatherPartsMat to use ColorOverride tint");
75 let Ok(color_override) = color_override.get(scene_ready.entity) else {
77 continue;
78 };
79 let mut new_material = material.clone();
84 new_material.base_color = color_override.0;
85
86 commands
88 .entity(descendant)
89 .insert(MeshMaterial3d(asset_materials.add(new_material)));
90 }
91 name => {
92 info!("not replacing: {name}");
93 }
94 }
95 }
96}