Add observable OnCollisionStart and OnCollisionEnd events#704
Merged
Conversation
Jondolf
added a commit
that referenced
this pull request
May 4, 2025
…717) # Objective #704 added observable `OnCollisionStart` and `OnCollisionEnd` events. However, they only provide the collider entity, and that is also just behind a nameless tuple field. It could be nicer to use named fields and also provide the rigid body entity. ## Solution Use named `collider` and `rigid_body` fields. `rigid_body` is `None` if the collider is not attached to a rigid body.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Objective
Closes #361.
Closes #481.
A common user request is to allow listening to collision events for specific entities, with an API where you don't need to check e.g. which entity is the player and which entity is an enemy like you might need to do when using
CollisionStartedandCollisionEnded. The typical Bevy API for per-entity events like this is observers.On the surface, this is a straightforward addition. However, there have historically been some challenges and open questions:
CollisionStartedandCollisionEndeddo. TheTriggeralready stores the observed entity.Now that #683 made collision events opt-in via the
CollisionEventsEnabledcomponent, I consider (1) to be solved. We can only trigger the event for entities with that component. The other two are more just a matter of how we want to design this, but I would assert that (2) we should just have separate types for buffered and observable events, and (3) we should trigger the events after the solver, because having access to contact impulses is valuable, even if it has a small extra cost.Solution
Add
OnCollisionStartandOnCollisionEndevents that are triggered when an entity starts or stops colliding with another entity. The naming was chosen to be distinct enough fromCollisionStartedandCollisionEnded, while reflecting Bevy's observer event names such asOnAddorPointer<Move>(present tense verb).The events are triggered after the solver by iterating through the buffered events and checking which entities have
CollisionEventsEnabled. System-local buffers and exclusive world access are used to try and minimize overhead and unnecessary allocations.Usage of the events might look like this:
The system that triggers the events runs in a
CollisionEventSystemssystem set in a newPhysicsStepSet::Finalizesystem set right beforePhysicsStepSet::Last.