# Picking and Pointer Events for Bevy [![crates.io](https://img.shields.io/crates/v/bevy_mod_picking)](https://crates.io/crates/bevy_mod_picking) [![docs.rs](https://docs.rs/bevy_mod_picking/badge.svg)](https://docs.rs/bevy_mod_picking) [![CI](https://github.com/aevyrie/bevy_mod_picking/actions/workflows/rust.yml/badge.svg?branch=main)](https://github.com/aevyrie/bevy_mod_picking/actions?query=workflow%3A%22CI%22+branch%3Amain) ![demo](https://user-images.githubusercontent.com/2632925/235874600-de0c7720-6775-42e1-8650-41ee8ac68d1b.gif) A flexible set of plugins that add picking functionality to your [`bevy`](https://github.com/bevyengine/bevy) app. Want to drag a UI entity and drop it onto a 3D mesh entity? This plugin allows you to add event listeners to **any** entity, and works with mouse, touch, or even gamepads.
# Highlights - ***Lightweight***: only compile what you need. - ***Expressive***: event listener components `On::>::run(my_system)`. - ***Input Agnostic***: control pointers with mouse, pen, touch, or custom bevy systems. - ***Modular Backends***: mix and match backends like `rapier`, `egui`, `bevy_ui`, or write your own. ## Lightweight Only compile what you use. All non-critical plugins can be disabled, including highlighting, selection, and any backends not in use. The crate uses no external dependencies unless you need it for a backend, e.g. `egui` or `rapier`. ## Expressive The `On::>` event listener component makes it easy to react to pointer interactions like `Click`, `Over`, and `Drag`. Events bubble up the entity hierarchy starting from their target looking for event listeners, and running any listener's callbacks. These callbacks are normal bevy systems, though a number of helpers are provided to reduce boilerplate: ```rs commands.spawn(( PbrBundle { /* ... */ }, // These callbacks are run when this entity or its children are interacted with. On::>::run(change_hue_with_vertical_move), // Rotate an entity when dragged: On::>::target_component_mut::(|drag, transform| { transform.rotate_local_y(drag.delta.x / 50.0) }), // Despawn an entity when clicked: On::>::target_commands_mut(|_click, target_commands| { target_commands.despawn(); }), // Send an event when the pointer is pressed over this entity: On::>::send_event::(), )); ``` If you don't need event bubbling or callbacks, you can respond to pointer events like you would any other bevy event, using `EventReader>`, `EventReader>`, etc. ## Input Agnostic Pointers can be controlled with anything, whether it's the included mouse or touch inputs, or a custom gamepad input system you write yourself. ## Modular Backends Picking backends run hit tests to determine if a pointer is over any entities. This plugin provides an [extremely simple API to write your own backend](crates/bevy_picking_core/src/backend.rs) in about 100 lines of code; it also includes half a dozen backends out of the box. These include `rapier`, `egui`, and `bevy_ui`, among others. Multiple backends can be used at the same time! You can have a simple rect hit test backend for your UI, a GPU picking shader for your 3D scene, and this plugin will handle sorting hits and generating events. ## Robust In addition to these features, this plugin also correctly handles multitouch, multiple windows, render layers, viewports, and camera order. # Getting Started Making objects pickable is pretty straightforward. In the most minimal cases, it's as simple as adding the plugin to your app: ```rs .add_plugins(DefaultPickingPlugins) ``` and adding the `PickableBundle` to entities that can be picked with the backends you are using: ```rs commands.spawn(( PbrBundle::default(), // The `bevy_picking_raycast` backend works with meshes PickableBundle::default(), // Makes the entity pickable )); ``` You can find a list of built-in backends [here](https://docs.rs/bevy_mod_picking/latest/bevy_mod_picking/backends/index.html) ## Next Steps To learn more, [read the docs](https://docs.rs/bevy_mod_picking/latest/bevy_mod_picking/) and take a look at the examples in the `/examples` directory. Understanding [bevy_eventlistener](https://github.com/aevyrie/bevy_eventlistener) will also help. Once you are comfortable with that, this crate's `event_listener` example is a great place to start. # Bevy Version Support | bevy | bevy_mod_picking | | ---- | ---------------- | | 0.14 | 0.20 | | 0.13 | 0.18, 0.19 | | 0.12 | 0.17 | | 0.11 | 0.15, 0.16 | | 0.10 | 0.12, 0.13, 0.14 | | 0.9 | 0.10, 0.11 | | 0.8 | 0.8, 0.9 | | 0.7 | 0.6, 0.7 | | 0.6 | 0.5 | | 0.5 | 0.4 | | 0.4 | 0.3 | | 0.3 | 0.2 | | 0.2 | 0.1 | # License All code in this repository is dual-licensed under either: - MIT License (LICENSE-MIT or http://opensource.org/licenses/MIT) - Apache License, Version 2.0 (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0) at your option. This means you can select the license you prefer. ## Your contributions Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.