93 lines
2.7 KiB
Rust
93 lines
2.7 KiB
Rust
use bevy::{
|
|
gltf::GltfMaterialName,
|
|
pbr::{ExtendedMaterial, MaterialExtension},
|
|
prelude::*,
|
|
render::render_resource::AsBindGroup,
|
|
shader::ShaderRef,
|
|
world_serialization::WorldInstanceReady,
|
|
};
|
|
|
|
pub type FighterMaterial = ExtendedMaterial<StandardMaterial, FighterMaterialExtension>;
|
|
|
|
#[derive(Component)]
|
|
pub struct FighterMesh {
|
|
pub fighter: Entity,
|
|
}
|
|
|
|
#[derive(Asset, AsBindGroup, Reflect, Debug, Clone, Default)]
|
|
pub struct FighterMaterialExtension {
|
|
#[uniform(100)]
|
|
status_color: LinearRgba,
|
|
#[uniform(100)]
|
|
status_color_intensity: f32,
|
|
}
|
|
|
|
const SHADER_ASSET_PATH: &str = "embedded://shinespark/shaders/fighter.wgsl";
|
|
|
|
impl FighterMaterialExtension {
|
|
pub fn new(status_color: Color) -> Self {
|
|
Self {
|
|
status_color: status_color.into(),
|
|
status_color_intensity: 0.0,
|
|
..default()
|
|
}
|
|
}
|
|
|
|
pub fn update_status_color(&mut self, status_color: LinearRgba, intensity: f32) {
|
|
self.status_color = status_color;
|
|
self.status_color_intensity = intensity;
|
|
}
|
|
}
|
|
|
|
impl MaterialExtension for FighterMaterialExtension {
|
|
fn fragment_shader() -> ShaderRef {
|
|
SHADER_ASSET_PATH.into()
|
|
}
|
|
|
|
fn deferred_fragment_shader() -> ShaderRef {
|
|
SHADER_ASSET_PATH.into()
|
|
}
|
|
}
|
|
|
|
pub fn bind_fighter_material(
|
|
scene_ready: On<WorldInstanceReady>,
|
|
mut commands: Commands,
|
|
children: Query<&Children>,
|
|
//color_override: Query<&ColorOverride>,
|
|
mesh_materials: Query<(Entity, &MeshMaterial3d<StandardMaterial>, &GltfMaterialName)>,
|
|
mut asset_materials: ResMut<Assets<FighterMaterial>>,
|
|
original_materials: Res<Assets<StandardMaterial>>,
|
|
) {
|
|
for descendant in children.iter_descendants(scene_ready.entity) {
|
|
let Ok((entity, id, material_name)) = mesh_materials.get(descendant) else {
|
|
continue;
|
|
};
|
|
|
|
if !material_name.starts_with("Fighter_") {
|
|
continue;
|
|
}
|
|
|
|
let Some(original_material) = original_materials.get(id.id()) else {
|
|
continue;
|
|
};
|
|
|
|
commands
|
|
.entity(entity)
|
|
.remove::<MeshMaterial3d<StandardMaterial>>()
|
|
.insert((
|
|
MeshMaterial3d(asset_materials.add(ExtendedMaterial {
|
|
base: StandardMaterial {
|
|
// can be used in forward or deferred mode
|
|
..original_material.clone()
|
|
},
|
|
extension: FighterMaterialExtension::new(
|
|
bevy::color::palettes::css::BLUE.into(),
|
|
),
|
|
})),
|
|
FighterMesh {
|
|
fighter: scene_ready.entity,
|
|
},
|
|
));
|
|
}
|
|
}
|