Update picking docs (#17057)

More updates to picking docs. Addresses some nits with wording, and
fixes some out of date information.
This commit is contained in:
Aevyrie 2024-12-30 17:56:45 -08:00 committed by GitHub
parent f3da36c181
commit 63634fd408
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -1,12 +1,14 @@
//! This crate provides 'picking' capabilities for the Bevy game engine. That means, in simple terms, figuring out //! This crate provides 'picking' capabilities for the Bevy game engine, allowing pointers to
//! how to connect up a user's clicks or taps to the entities they are trying to interact with. //! interact with entities using hover, click, and drag events.
//! //!
//! ## Overview //! ## Overview
//! //!
//! In the simplest case, this plugin allows you to click on things in the scene. However, it also //! In the simplest case, this plugin allows you to click on things in the scene. However, it also
//! allows you to express more complex interactions, like detecting when a touch input drags a UI //! allows you to express more complex interactions, like detecting when a touch input drags a UI
//! element and drops it on a 3d mesh rendered to a different camera. The crate also provides a set of //! element and drops it on a 3d mesh rendered to a different camera.
//! interaction callbacks, allowing you to receive input directly on entities like here: //!
//! Pointer events bubble up the entity hieararchy and can be used with observers, allowing you to
//! succinctly express rich interaction behaviors by attaching pointer callbacks to entities:
//! //!
//! ```rust //! ```rust
//! # use bevy_ecs::prelude::*; //! # use bevy_ecs::prelude::*;
@ -16,7 +18,8 @@
//! # let mut world = World::new(); //! # let mut world = World::new();
//! world.spawn(MyComponent) //! world.spawn(MyComponent)
//! .observe(|mut trigger: Trigger<Pointer<Click>>| { //! .observe(|mut trigger: Trigger<Pointer<Click>>| {
//! // Get the underlying event type //! println!("I was just clicked!");
//! // Get the underlying pointer event data
//! let click_event: &Pointer<Click> = trigger.event(); //! let click_event: &Pointer<Click> = trigger.event();
//! // Stop the event from bubbling up the entity hierarchy //! // Stop the event from bubbling up the entity hierarchy
//! trigger.propagate(false); //! trigger.propagate(false);
@ -24,16 +27,19 @@
//! ``` //! ```
//! //!
//! At its core, this crate provides a robust abstraction for computing picking state regardless of //! At its core, this crate provides a robust abstraction for computing picking state regardless of
//! pointing devices, or what you are hit testing against. It is designed to work with any input, including //! pointing devices, or what you are hit testing against. It is designed to work with any input,
//! mouse, touch, pens, or virtual pointers controlled by gamepads. //! including mouse, touch, pens, or virtual pointers controlled by gamepads.
//! //!
//! ## Expressive Events //! ## Expressive Events
//! //!
//! The events in this module (see [`events`]) cannot be listened to with normal `EventReader`s. //! Although the events in this module (see [`events`]) can be listened to with normal
//! Instead, they are dispatched to *observers* attached to specific entities. When events are generated, they //! `EventReader`s, using observers is often more expressive, with less boilerplate. This is because
//! bubble up the entity hierarchy starting from their target, until they reach the root or bubbling is halted //! observers allow you to attach event handling logic to specific entities, as well as make use of
//! with a call to [`Trigger::propagate`](bevy_ecs::observer::Trigger::propagate). //! event bubbling.
//! See [`Observer`] for details. //!
//! When events are generated, they bubble up the entity hierarchy starting from their target, until
//! they reach the root or bubbling is halted with a call to
//! [`Trigger::propagate`](bevy_ecs::observer::Trigger::propagate). See [`Observer`] for details.
//! //!
//! This allows you to run callbacks when any children of an entity are interacted with, and leads //! This allows you to run callbacks when any children of an entity are interacted with, and leads
//! to succinct, expressive code: //! to succinct, expressive code:
@ -74,8 +80,9 @@
//! #### Input Agnostic //! #### Input Agnostic
//! //!
//! Picking provides a generic Pointer abstraction, which is useful for reacting to many different //! Picking provides a generic Pointer abstraction, which is useful for reacting to many different
//! types of input devices. Pointers can be controlled with anything, whether it's the included mouse //! types of input devices. Pointers can be controlled with anything, whether it's the included
//! or touch inputs, or a custom gamepad input system you write yourself to control a virtual pointer. //! mouse or touch inputs, or a custom gamepad input system you write yourself to control a virtual
//! pointer.
//! //!
//! ## Robustness //! ## Robustness
//! //!
@ -90,8 +97,8 @@
//! #### Next Steps //! #### Next Steps
//! //!
//! To learn more, take a look at the examples in the //! To learn more, take a look at the examples in the
//! [examples](https://github.com/bevyengine/bevy/tree/main/examples/picking). You //! [examples](https://github.com/bevyengine/bevy/tree/main/examples/picking). You can read the next
//! can read the next section to understand how the plugin works. //! section to understand how the plugin works.
//! //!
//! # The Picking Pipeline //! # The Picking Pipeline
//! //!
@ -101,11 +108,11 @@
//! #### Pointers ([`pointer`](mod@pointer)) //! #### Pointers ([`pointer`](mod@pointer))
//! //!
//! The first stage of the pipeline is to gather inputs and update pointers. This stage is //! The first stage of the pipeline is to gather inputs and update pointers. This stage is
//! ultimately responsible for generating [`PointerInput`](pointer::PointerInput) events. The provided //! ultimately responsible for generating [`PointerInput`](pointer::PointerInput) events. The
//! crate does this automatically for mouse, touch, and pen inputs. If you wanted to implement your own //! provided crate does this automatically for mouse, touch, and pen inputs. If you wanted to
//! pointer, controlled by some other input, you can do that here. The ordering of events within the //! implement your own pointer, controlled by some other input, you can do that here. The ordering
//! [`PointerInput`](pointer::PointerInput) stream is meaningful for events with the same //! of events within the [`PointerInput`](pointer::PointerInput) stream is meaningful for events
//! [`PointerId`](pointer::PointerId), but not between different pointers. //! with the same [`PointerId`](pointer::PointerId), but not between different pointers.
//! //!
//! Because pointer positions and presses are driven by these events, you can use them to mock //! Because pointer positions and presses are driven by these events, you can use them to mock
//! inputs for testing. //! inputs for testing.
@ -115,18 +122,18 @@
//! //!
//! #### Backend ([`backend`]) //! #### Backend ([`backend`])
//! //!
//! A picking backend only has one job: reading [`PointerLocation`](pointer::PointerLocation) components, //! A picking backend only has one job: reading [`PointerLocation`](pointer::PointerLocation)
//! and producing [`PointerHits`](backend::PointerHits). You can find all documentation and types needed to //! components, and producing [`PointerHits`](backend::PointerHits). You can find all documentation
//! implement a backend at [`backend`]. //! and types needed to implement a backend at [`backend`].
//! //!
//! You will eventually need to choose which picking backend(s) you want to use. This crate does not //! You will eventually need to choose which picking backend(s) you want to use. This crate does not
//! supply any backends, and expects you to select some from the other bevy crates or the third-party //! supply any backends, and expects you to select some from the other bevy crates or the
//! ecosystem. //! third-party ecosystem.
//! //!
//! It's important to understand that you can mix and match backends! For example, you might have a //! It's important to understand that you can mix and match backends! For example, you might have a
//! backend for your UI, and one for the 3d scene, with each being specialized for their purpose. //! backend for your UI, and one for the 3d scene, with each being specialized for their purpose.
//! Bevy provides some backends out of the box, but you can even write your own. It's been //! Bevy provides some backends out of the box, but you can even write your own. It's been made as
//! made as easy as possible intentionally; the `bevy_mod_raycast` backend is 50 lines of code. //! easy as possible intentionally; the `bevy_mod_raycast` backend is 50 lines of code.
//! //!
//! #### Hover ([`hover`]) //! #### Hover ([`hover`])
//! //!
@ -135,8 +142,8 @@
//! just because a pointer is over an entity, it is not necessarily *hovering* that entity. Although //! just because a pointer is over an entity, it is not necessarily *hovering* that entity. Although
//! multiple backends may be reporting that a pointer is hitting an entity, the hover system needs //! multiple backends may be reporting that a pointer is hitting an entity, the hover system needs
//! to determine which entities are actually being hovered by this pointer based on the pick depth, //! to determine which entities are actually being hovered by this pointer based on the pick depth,
//! order of the backend, and the optional [`PickingBehavior`] component of the entity. In other words, //! order of the backend, and the optional [`PickingBehavior`] component of the entity. In other
//! if one entity is in front of another, usually only the topmost one will be hovered. //! words, if one entity is in front of another, usually only the topmost one will be hovered.
//! //!
//! #### Events ([`events`]) //! #### Events ([`events`])
//! //!
@ -144,9 +151,8 @@
//! a pointer hovers or clicks an entity. These simple events are then used to generate more complex //! a pointer hovers or clicks an entity. These simple events are then used to generate more complex
//! events for dragging and dropping. //! events for dragging and dropping.
//! //!
//! Because it is completely agnostic to the earlier stages of the pipeline, you can easily //! Because it is completely agnostic to the earlier stages of the pipeline, you can easily extend
//! extend the plugin with arbitrary backends and input methods, yet still use all the high level //! the plugin with arbitrary backends and input methods, yet still use all the high level features.
//! features.
#![deny(missing_docs)] #![deny(missing_docs)]