diff --git a/bevy/README.md b/bevy/README.md index 03b9924..c66bb21 100644 --- a/bevy/README.md +++ b/bevy/README.md @@ -59,6 +59,10 @@ struct GreetTimer(Timer); ``` # [three_d_shapes](three_d_shapes/src/main.rs) +- from bevy example # [pong](pong/src/main.rs) -- from tutorial https://taintedcoders.com/bevy/pong-tutorial/ \ No newline at end of file +- from tutorial https://taintedcoders.com/bevy/pong-tutorial/ + +# [picking](picking/src/main.rs) +- from **bevy_mod_picking** crate **event_listener** example https://github.com/aevyrie/bevy_mod_picking/blob/main/examples/event_listener.rs \ No newline at end of file diff --git a/bevy/picking/Cargo.toml b/bevy/picking/Cargo.toml new file mode 100644 index 0000000..ba831d5 --- /dev/null +++ b/bevy/picking/Cargo.toml @@ -0,0 +1,19 @@ +[package] +name = "picking" +version = "0.1.0" +edition = "2021" + +[dependencies] +bevy = { version = "0.13.2", features = ["dynamic_linking"] } +bevy_egui = "0.27.1" +bevy_mod_picking = { version = "0.19.0", features = ["all"] } + +# Enable a small amount of optimization in debug mode +[profile.dev] +opt-level = 1 + +# Enable high optimizations for dependencies (incl. Bevy), but not for our code: +[profile.dev.package."*"] +opt-level = 3 + +[workspace] diff --git a/bevy/picking/src/main.rs b/bevy/picking/src/main.rs new file mode 100644 index 0000000..06e8dd3 --- /dev/null +++ b/bevy/picking/src/main.rs @@ -0,0 +1,161 @@ +//! This example demonstrates how [`On`] components and event bubbling can be used to +//! propagate events up an entity hierarchy, and run callbacks when an event reaches an entity. +//! +//! The Big Idea here is to make it easy to couple interaction events with specific entities. In +//! other words, it allows you to easily implement "If entity X is hovered/clicked/dragged, do Y". + +use bevy::prelude::*; +use bevy_mod_picking::prelude::*; + +fn main() { + App::new() + .add_plugins(( + DefaultPlugins.set(low_latency_window_plugin()), + DefaultPickingPlugins + .build() + .disable::(), + bevy_egui::EguiPlugin, + )) + .insert_resource(DebugPickingMode::Normal) + .add_systems(Startup, setup) + .add_event::() + .add_systems( + Update, + receive_greetings.run_if(on_event::()), + ) + .run(); +} + +fn setup( + mut commands: Commands, + mut meshes: ResMut>, + mut materials: ResMut>, +) { + commands + // When any of this entity's children are interacted with using a pointer, those events will + // propagate up the entity hierarchy until they reach this parent. By referring to the + // `target` entity instead of the `listener` entity, we can do things to specific target + // entities, even though they lack `On>` components. + .spawn(( + PbrBundle { + mesh: meshes.add(Cuboid::default()), + material: materials.add(Color::WHITE), + ..default() + }, + PickableBundle::default(), + // Callbacks are just exclusive bevy systems that have access to an event data via + // `](bevy_eventlistener::prelude::Listener) and [`ListenerMut`]. This gives + // you full freedom to write normal bevy + // systems that are only called when specific entities are interacted with. Here we have + // a system that rotates a cube when it is dragged. See the comments added to the + // function for more details on the requirements of callback systems. + // + // # Performance 💀 + // + // Callback systems require exclusive world access, which means the system cannot be run + // in parallel with other systems! Callback systems are very flexible, but should be + // used with care. If you want to do something complex in response to a listened event, + // prefer to instead use `send_event`, and react to your custom event in a + // normally-scheduled bevy system (see send_event usage below). + On::>::run(change_hue_with_vertical_move), + // We can use helper methods to make callbacks even simpler. For drag-to-rotate, we use + // this little closure, because we only need to modify the target entity's Transform: + On::>::target_component_mut::(|drag, transform| { + transform.rotate_local_y(drag.delta.x / 50.0) + }), + // Just like bevy systems, callbacks can be closures! Recall that the parameters can be + // any bevy system parameters, with the only requirement that the first parameter be the + // input event, and the function output is a `Bubble`. + On::>::run(|event: Listener>, time: Res