2021-09-30 20:31:47 +00:00
|
|
|
use bevy::prelude::*;
|
|
|
|
|
|
|
|
use crate::player::Player;
|
|
|
|
|
2021-10-01 17:56:26 +00:00
|
|
|
const RANGE: f32 = 25.0;
|
|
|
|
|
2021-09-30 20:31:47 +00:00
|
|
|
pub struct LightBall;
|
|
|
|
pub fn light_up_ball_when_close_to_player(
|
|
|
|
mut commands: Commands,
|
|
|
|
player: Query<(&Transform, &Player), Without<LightBall>>,
|
|
|
|
mut thingies: Query<(
|
|
|
|
Entity,
|
|
|
|
&Transform,
|
|
|
|
&LightBall,
|
|
|
|
&mut Handle<StandardMaterial>,
|
|
|
|
Option<&mut Light>,
|
|
|
|
)>,
|
|
|
|
materials: Res<LightBallMaterials>,
|
|
|
|
) {
|
|
|
|
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);
|
2021-10-01 17:56:26 +00:00
|
|
|
if dis < RANGE {
|
2021-09-30 20:31:47 +00:00
|
|
|
*material = materials.lit.clone();
|
|
|
|
|
|
|
|
// change intensity,
|
|
|
|
// add light if there isn't one
|
|
|
|
if let Some(mut l) = light {
|
2021-10-01 17:56:26 +00:00
|
|
|
l.intensity = 300.0 * (RANGE - dis) / RANGE;
|
2021-09-30 20:31:47 +00:00
|
|
|
} else {
|
|
|
|
commands.entity(entity).insert(Light {
|
|
|
|
color: Color::rgb(15.0, 15.0, 15.0),
|
2021-10-01 17:56:26 +00:00
|
|
|
intensity: 300.0 * (RANGE - dis) / RANGE,
|
2021-09-30 20:31:47 +00:00
|
|
|
..Default::default()
|
|
|
|
});
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
*material = materials.unlit.clone();
|
|
|
|
|
|
|
|
// remove light if there is one
|
|
|
|
if light.is_some() {
|
|
|
|
commands.entity(entity).remove::<Light>();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
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<StandardMaterial>,
|
|
|
|
lit: Handle<StandardMaterial>,
|
|
|
|
mesh: Handle<Mesh>,
|
|
|
|
}
|
|
|
|
impl FromWorld for LightBallMaterials {
|
|
|
|
fn from_world(world: &mut World) -> Self {
|
|
|
|
let world = world.cell();
|
|
|
|
let mut materials = world
|
|
|
|
.get_resource_mut::<Assets<StandardMaterial>>()
|
|
|
|
.unwrap();
|
|
|
|
let mut meshes = world.get_resource_mut::<Assets<Mesh>>().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 }
|
|
|
|
}
|
|
|
|
}
|