bevy/release-content/migration-guides/pointer_target.md
Alice Cecile b7d2cb8547
Provide access to the original target of entity-events in observers (#19663)
# Objective

Getting access to the original target of an entity-event is really
helpful when working with bubbled / propagated events.

`bevy_picking` special-cases this, but users have requested this for all
sorts of bubbled events.

The existing naming convention was also very confusing. Fixes
https://github.com/bevyengine/bevy/issues/17112, but also see #18982.

## Solution

1. Rename `ObserverTrigger::target` -> `current_target`.
1. Store `original_target: Option<Entity>` in `ObserverTrigger`.
1. Wire it up so this field gets set correctly.
1. Remove the `target` field on the `Pointer` events from
`bevy_picking`.

Closes https://github.com/bevyengine/bevy/pull/18710, which attempted
the same thing. Thanks @emfax!

## Testing

I've modified an existing test to check that the entities returned
during event bubbling / propagation are correct.

## Notes to reviewers

It's a little weird / sad that you can no longer access this infromation
via the buffered events for `Pointer`. That said, you already couldn't
access any bubbled target. We should probably remove the `BufferedEvent`
form of `Pointer` to reduce confusion and overhead, but I didn't want to
do so here.

Observer events can be trivially converted into buffered events (write
an observer with an EventWriter), and I suspect that that is the better
migration if you want the controllable timing or performance
characteristics of buffered events for your specific use case.

## Future work

It would be nice to not store this data at all (and not expose any
methods) if propagation was disabled. That involves more trait
shuffling, and I don't think we should do it here for reviewability.

---------

Co-authored-by: Joona Aalto <jondolf.dev@gmail.com>
2025-06-15 20:53:25 +00:00

1.2 KiB

title pull_requests
Original target of `Pointer` picking events is now stored on observers
19663

The Pointer.target field, which tracks the original target of the pointer event before bubbling, has been removed. Instead, all observers now track this information, available via the On::original_target() method.

If you were using this information via the buffered event API of picking, please migrate to observers. If you cannot for performance reasons, please open an issue explaining your exact use case!

As a workaround, you can transform any entity-event into a buffered event that contains the targeted entity using an observer than emits events.

#[derive(Event, BufferedEvent)]
struct TransformedEntityEvent<E: EntityEvent> {
    entity: Entity,
    event: E,
}

// A generic observer that handles this transformation
fn transform_entity_event<E: EntityEvent>(trigger: On<E>, event_writer: EventWriter<TransformedEntityEvent<E>>){
    if trigger.target() == trigger.original_target(){
        event_writer.send(trigger.event())
    }
}

Additionally, the ObserverTrigger::target field has been renamed to ObserverTrigger::current_target and a new ObserverTrigger::original_target field has been added.