use std::time::Duration;
use bevy::{core_pipeline::tonemapping::Tonemapping, prelude::*};
use bevy_hanabi::prelude::*;
mod utils;
use utils::*;
const DEMO_DESC: &str = include_str!("visibility.txt");
fn main() -> Result<(), Box<dyn std::error::Error>> {
let app_exit = utils::DemoApp::new("visibility")
.with_desc(DEMO_DESC)
.build()
.add_systems(Startup, setup)
.add_systems(Update, update)
.run();
app_exit.into_result()
}
fn setup(
mut commands: Commands,
mut effects: ResMut<Assets<EffectAsset>>,
mut meshes: ResMut<Assets<Mesh>>,
mut materials: ResMut<Assets<StandardMaterial>>,
) {
commands.spawn((
Transform::from_translation(Vec3::Z * 100.),
Camera3d::default(),
Tonemapping::None,
));
commands.spawn(DirectionalLight {
color: Color::WHITE,
illuminance: 100000.,
shadows_enabled: false,
..Default::default()
});
let cube = meshes.add(Cuboid {
half_size: Vec3::splat(0.5),
});
let mat = materials.add(utils::COLOR_PURPLE);
let mut gradient = bevy_hanabi::Gradient::new();
gradient.add_key(0.0, Vec4::new(1.0, 0.0, 0.0, 1.0));
gradient.add_key(0.25, Vec4::new(0.0, 1.0, 0.0, 1.0));
gradient.add_key(0.5, Vec4::new(0.0, 0.0, 1.0, 1.0));
gradient.add_key(0.75, Vec4::new(0.0, 1.0, 1.0, 1.0));
gradient.add_key(1.0, Vec4::new(1.0, 1.0, 1.0, 1.0));
let writer = ExprWriter::new();
let velocity = writer.lit(Vec3::X * 3.).expr();
let init_velocity = SetAttributeModifier::new(Attribute::VELOCITY, velocity);
let age = writer.lit(0.).expr();
let init_age = SetAttributeModifier::new(Attribute::AGE, age);
let lifetime = writer.lit(15.).expr();
let init_lifetime = SetAttributeModifier::new(Attribute::LIFETIME, lifetime);
let init_pos = SetPositionSphereModifier {
center: writer.lit(Vec3::ZERO).expr(),
radius: writer.lit(5.).expr(),
dimension: ShapeDimension::Volume,
};
let mut asset = EffectAsset::new(
4096,
SpawnerSettings::burst(50.0.into(), 15.0.into()),
writer.finish(),
)
.with_simulation_condition(SimulationCondition::WhenVisible)
.init(init_pos)
.init(init_velocity)
.init(init_age)
.init(init_lifetime)
.render(ColorOverLifetimeModifier::new(gradient));
let effect1 = effects.add(asset.clone());
commands
.spawn((
Transform::from_translation(Vec3::new(-30., -20., 0.)),
Mesh3d(cube.clone()),
MeshMaterial3d(mat.clone()),
))
.with_children(|p| {
p.spawn((Name::new("WhenVisible"), ParticleEffect::new(effect1)));
});
asset.simulation_condition = SimulationCondition::Always;
let effect2 = effects.add(asset);
commands
.spawn((
Transform::from_translation(Vec3::new(-30., 20., 0.)),
Mesh3d(cube.clone()),
MeshMaterial3d(mat.clone()),
))
.with_children(|p| {
p.spawn((Name::new("Always"), ParticleEffect::new(effect2)));
});
}
fn update(
time: Res<Time>,
mut last_time: Local<u64>,
mut query: Query<&mut Visibility, With<ParticleEffect>>,
) {
if time.elapsed() - Duration::from_millis(*last_time) >= Duration::from_millis(1500) {
*last_time = time.elapsed().as_millis() as u64;
for mut visibility in query.iter_mut() {
*visibility = if *visibility == Visibility::Visible {
Visibility::Hidden
} else {
Visibility::Visible
};
}
}
}