Contact Detection
chessboy opened this issue · 3 comments
First, let me say this is one hell of a useful library, and thank you for the hard work! I've ported most of my app (which used a homegrown ECS) to OctopusKit and everything is so much cleaner, and will probably be more performant when all is said and done.
The only thing I'm stuck on is getting contact events. Are PhysicsEventComponent
and PhysicsContactHandlerComponent
supposed to be added to the scene's entity or to the individual "monster" entities?
Thanks for any info!
Rob
Woo, first user (who talked)! Thanks!
PhysicsContactHandlerComponent
to PhysicsContactComponent
just after writing this reply.
A PhysicsEventComponent
is like a TouchEventComponent
; it makes more sense to create just one on a scene's entity, then share it with child entities via multiple RelayComponent
s.
Every OctopusScene
has a lazy sharedPhysicsEventComponent
property. Your child entities can access it via a RelayComponent(for: scene.sharedPhysicsEventComponent)
ℹ️ A PhysicsContactComponent
reads the PhysicsEventComponent
of its entity (or from a relay) during its update(deltaTime:)
method, and looks for events which involve the PhysicsComponent
body of its entity.
ℹ️ If an entity's physics body is involved in a contact event, then that entity's PhysicsContactComponent
calls its didBegin(_:in:)
or didEnd(_:in:)
method.
❗️Your scene's physicsWorld.contactDelegate
property should be set to the scene itself, otherwise the scene's PhysicsEventComponent
will not receive any events! (This is automatically done if you add a PhysicsWorldComponent
to the scene entity.)
❗️ Your physics bodies should have the contactTestBitMask
and other related properties set on them.
❗️ PhysicsEventComponent
and PhysicsContactComponent
need to be updated every frame, so create component systems for them (and for their subclasses, if any)! Contact handling components need to be updated after the Event component, so be mindful of the order of component systems as well.
You must create a subclass of PhysicsContactComponent
, for example a MonsterContactComponent
and add it to all monster entities (and of course, remember to create a component system for MonsterContactComponent.self
)
Your PhysicsContactComponent
should override at least the didBegin(_:in:)
method, and use it to decide what happens when a monster is involved in any physics collisions (after checking the arguments passed to that method to inspect the scene and other bodies.)
💡 You can also add the LOGPHYSICS
custom compilation flag to see some debug info.
...whew! I know, tasks like that should have some kind of tutorials or documentation, but I haven't gotten around to writing those yet. 😔
Let me know if you still can't get it work. I might post some sample code later.
Wow, that was easy. Using RelayComponent(for: scene.sharedPhysicsEventComponent)
did the trick. Now getting calls to didBegin(_:in:)
in my subclass of PhysicsContactHandlerComponent
. Thanks for the help!
Yeah, I have to add some log warnings to those components for common mistakes/confusions like that.