InvadingOctopus/octopuskit

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!

⚠️ NOTE: I shortened 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 RelayComponents.

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.