pub fn pointer_events(
input_events: MessageReader<'_, '_, PointerInput>,
pointers: Query<'_, '_, &PointerLocation>,
ancestors_query: Query<'_, '_, &ChildOf>,
pointer_map: Res<'_, PointerMap>,
hover_map: Res<'_, HoverMap>,
previous_hover_map: Res<'_, PreviousHoverMap>,
picking_settings: Res<'_, PickingSettings>,
pointer_state: ResMut<'_, PointerState>,
hovered_entity_ancestors: Local<'_, HoveredEntityAncestors>,
sent_leave: Local<'_, HashSet<(PointerId, Entity)>>,
sent_enter: Local<'_, HashSet<(PointerId, Entity)>>,
commands: Commands<'_, '_>,
message_writers: PickingMessageWriters<'_>,
)Expand description
Dispatches interaction events to the target entities.
Within a single frame, events are dispatched in the following order:
PointerOut→PointerLeave→PointerDragLeave.PointerDragEnter→PointerEnter→PointerOver.- Any number of any of the following:
- For each movement:
PointerDragStart→PointerDrag→PointerDragOver→PointerMove. - For each button press:
PointerPressorPointerClick→PointerRelease→PointerDragDrop→PointerDragEnd→PointerDragLeave. - For each pointer cancellation:
PointerCancel.
- For each movement:
Additionally, across multiple frames, the following are also strictly ordered by the interaction state machine:
- When a pointer moves over the target:
PointerOver,PointerEnter,PointerMove,PointerLeave,PointerOut. - When a pointer presses buttons on the target:
PointerPress,PointerClick,PointerRelease. - When a pointer drags the target:
PointerDragStart,PointerDrag,PointerDragEnd. - When a pointer drags something over the target:
PointerDragEnter,PointerDragOver,PointerDragDrop,PointerDragLeave. - When a pointer is canceled:
No other events will follow the
PointerCancelevent for that pointer.
Four events – PointerOver, PointerEnter, PointerLeave and PointerOut – are driven only by the HoverMap.
The rest rely on additional data from the PointerInput event stream. To
receive these events for a custom pointer, you must add PointerInput
events.
When the pointer goes from hovering entity A to entity B, entity A will
receive PointerOut and PointerEnter and then entity B will receive PointerLeave and PointerOver.
No entity will ever receive both an PointerOver and an PointerOut or
an PointerEnter and a PointerLeave event during the same frame.
When we account for event bubbling, the two pairs of events,
PointerOut PointerOver and PointerEnter PointerLeave, behave differently. When the hovering focus shifts
between children, parent entities may receive redundant PointerOut → PointerOver pairs. In
the case of PointerEnter → PointerLeave, shared parent entities will not receive PointerEnter
or PointerLeave.
Both PointerClick and PointerRelease target the entity hovered in the previous frame,
rather than the current frame. This is because touch pointers hover nothing
on the frame they are released. The end effect is that these two events can
be received sequentially after an PointerOut event (but always on the same frame
as the PointerOut event).
Note: Though it is common for the PointerInput stream may contain
multiple pointer movements and presses each frame, the hover state is
determined only by the pointer’s final position. Since the hover state
ultimately determines which entities receive events, this may mean that an
entity can receive events from before or after it was actually hovered.