diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 5d3be040..80374f47 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -123,19 +123,19 @@ jobs: for example in .github/example-run/3d/*.ron; do example_name=`basename $example .ron` echo "running $example_name - "`date` - time CI_TESTING_CONFIG=$example xvfb-run cargo run --example $example_name --no-default-features --features="bevy/bevy_winit bevy/bevy_pbr 3d bevy/bevy_ci_testing" + time CI_TESTING_CONFIG=$example xvfb-run cargo run --example $example_name --no-default-features --features="bevy/bevy_winit bevy/bevy_pbr bevy/bevy_ui bevy/default_font 3d bevy/bevy_ci_testing" sleep 10 done for example in .github/example-run/3dpng/*.ron; do example_name=`basename $example .ron` echo "running $example_name - "`date` - time CI_TESTING_CONFIG=$example xvfb-run cargo run --example $example_name --no-default-features --features="bevy/bevy_winit bevy/bevy_pbr bevy/png 3d bevy/bevy_ci_testing" + time CI_TESTING_CONFIG=$example xvfb-run cargo run --example $example_name --no-default-features --features="bevy/bevy_winit bevy/bevy_pbr bevy/bevy_ui bevy/default_font bevy/png 3d bevy/bevy_ci_testing" sleep 10 done for example in .github/example-run/2d/*.ron; do example_name=`basename $example .ron` echo "running $example_name - "`date` - time CI_TESTING_CONFIG=$example xvfb-run cargo run --example $example_name --no-default-features --features="bevy/bevy_winit bevy/bevy_sprite 2d bevy/bevy_ci_testing" + time CI_TESTING_CONFIG=$example xvfb-run cargo run --example $example_name --no-default-features --features="bevy/bevy_winit bevy/bevy_sprite bevy/bevy_ui bevy/default_font 2d bevy/bevy_ci_testing" sleep 10 done env: diff --git a/Cargo.toml b/Cargo.toml index d226a11b..b74aaaa0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -110,7 +110,7 @@ required-features = [ "bevy/bevy_winit", "bevy/bevy_pbr", "3d" ] [[example]] name = "activate" -required-features = [ "bevy/bevy_winit", "bevy/bevy_pbr", "3d" ] +required-features = [ "bevy/bevy_winit", "bevy/bevy_pbr", "bevy/bevy_ui", "bevy/default_font", "3d" ] [[example]] name = "force_field" diff --git a/README.md b/README.md index 8c7db3a2..54f4a056 100644 --- a/README.md +++ b/README.md @@ -202,7 +202,7 @@ cargo run --example multicam --features="bevy/bevy_winit bevy/bevy_pbr 3d" ### Activate -This example demonstrates manual activation and deactivation of a spawner, from code (CPU). The circle bobs up and down in the water, spawning square bubbles when in the water only. +This example demonstrates manual activation and deactivation of a `Spawner`, from code (CPU). The circle bobs up and down in the water, spawning bubbles when in the water only. The bubble particles are constrained to the water with a `KillAabbModifier`, and a small vertical acceleration simulate some pseudo buoyancy. ```shell cargo run --example activate --features="bevy/bevy_winit bevy/bevy_pbr 3d" diff --git a/examples/activate.gif b/examples/activate.gif index 5c974152..8a7bddd2 100644 Binary files a/examples/activate.gif and b/examples/activate.gif differ diff --git a/examples/activate.rs b/examples/activate.rs index aba5f436..d58950f7 100644 --- a/examples/activate.rs +++ b/examples/activate.rs @@ -1,10 +1,14 @@ -//! A circle bobs up and down in the water, spawning square bubbles when in the -//! water. +//! A circle bobs up and down in the water, spawning bubbles when in the water. //! //! This example demonstrates the use of [`Spawner::set_active()`] to enable or //! disable particle spawning, under the control of the application. This is //! similar to the `spawn_on_command.rs` example, where [`Spawner::reset()`] is //! used instead to spawn a single burst of particles. +//! +//! A small vertical acceleration simulate a pseudo-buoyancy making the bubbles +//! slowly move upward toward the surface. The example uses a +//! [`KillAabbModifier`] to ensure the bubble particles never escape water, and +//! are despawned when reaching the surface. use bevy::{ core_pipeline::tonemapping::Tonemapping, @@ -58,6 +62,9 @@ fn main() -> Result<(), Box> { Ok(()) } +#[derive(Component)] +struct StatusText; + #[derive(Component)] struct Ball { velocity_y: f32, @@ -80,6 +87,7 @@ fn setup( camera.projection = Projection::Orthographic(projection); commands.spawn(camera); + // Blue rectangle mesh for "water" commands .spawn(PbrBundle { mesh: meshes.add(Rectangle { @@ -132,6 +140,14 @@ fn setup( speed: writer.lit(0.1).expr(), }; + let buoyancy = writer.lit(Vec3::Y * 0.2).expr(); + let update_buoyancy = AccelModifier::new(buoyancy); + + // Kill particles getting out of water + let center = writer.lit(Vec3::Y * -2.02).expr(); + let half_size = writer.lit(Vec3::splat(2.0)).expr(); + let allow_zone = KillAabbModifier::new(center, half_size); + let mut module = writer.finish(); let round = RoundModifier::constant(&mut module, 1.0); @@ -143,9 +159,10 @@ fn setup( .init(init_vel) .init(init_age) .init(init_lifetime) - .render(SizeOverLifetimeModifier { - gradient: Gradient::constant(Vec2::splat(0.02)), - screen_space_size: false, + .update(update_buoyancy) + .update(allow_zone) + .render(SetSizeModifier { + size: Vec2::splat(0.02).into(), }) .render(ColorOverLifetimeModifier { gradient }) .render(round), @@ -155,11 +172,33 @@ fn setup( node.spawn(ParticleEffectBundle::new(effect)) .insert(Name::new("effect")); }); + + commands.spawn(( + TextBundle { + style: Style { + position_type: PositionType::Absolute, + top: Val::Px(30.), + right: Val::Px(30.), + ..default() + }, + text: Text::from_section( + "Active", + TextStyle { + font_size: 60.0, + color: Color::WHITE, + ..default() + }, + ), + ..default() + }, + StatusText, + )); } fn update( mut q_balls: Query<(&mut Ball, &mut Transform, &Children)>, mut q_spawner: Query<&mut EffectSpawner>, + mut q_text: Query<&mut Text, With>, time: Res