//! 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_color::palettes; use bevy_mod_picking::prelude::*; fn main() { App::new() .add_plugins(( DefaultPlugins.set(low_latency_window_plugin()), DefaultPickingPlugins .build() .disable::(), )) .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