use bevy::prelude::*; use crate::player::Player; pub struct LightBall; pub fn light_up_ball_when_close_to_player( mut commands: Commands, player: Query<(&Transform, &Player), Without>, mut thingies: Query<( Entity, &Transform, &LightBall, &mut Handle, Option<&mut Light>, )>, materials: Res, ) { let player_pos = if let Some(player) = player.iter().next() { player.0.translation } else { return; }; for (entity, trans, _, mut material, light) in thingies.iter_mut() { let dis = trans.translation.distance(player_pos); if dis < 20.0 { *material = materials.lit.clone(); // change intensity, // add light if there isn't one if let Some(mut l) = light { l.intensity = 300.0 * (20.0 - dis) / 20.0; } else { commands.entity(entity).insert(Light { color: Color::rgb(15.0, 15.0, 15.0), intensity: 300.0 * (20.0 - dis) / 20.0, ..Default::default() }); } } else { *material = materials.unlit.clone(); // remove light if there is one if light.is_some() { commands.entity(entity).remove::(); } } } } pub fn spawn_light_ball( commands: &mut Commands, materials: &LightBallMaterials, translation: Vec3, ) { commands .spawn_bundle(PbrBundle { mesh: materials.mesh.clone(), material: materials.unlit.clone(), transform: Transform::from_translation(translation), ..Default::default() }) .insert(LightBall); } pub struct LightBallMaterials { unlit: Handle, lit: Handle, mesh: Handle, } impl FromWorld for LightBallMaterials { fn from_world(world: &mut World) -> Self { let world = world.cell(); let mut materials = world .get_resource_mut::>() .unwrap(); let mut meshes = world.get_resource_mut::>().unwrap(); let mut unlit: StandardMaterial = Color::rgb(0.9, 0.9, 0.9).into(); unlit.metallic = 0.0; unlit.reflectance = 0.0; let unlit = materials.add(unlit); let mut lit: StandardMaterial = Color::rgb(15.0, 15.0, 15.0).into(); lit.metallic = 0.5; lit.reflectance = 0.5; lit.emissive = Color::rgb(15.0, 15.0, 15.0); let lit = materials.add(lit); let mesh = meshes.add(Mesh::from(shape::Icosphere { radius: 2.0, subdivisions: 5, })); Self { lit, unlit, mesh } } }