Reputation: 908
I'm trying to build a game using ARkit and SceneKit, but after setting up the physicsWorld delegate and the physics body of the objects, the delegate method didBeginContact is not called.
This is my struct for physics body
struct CollisionCategory {
static let moltenBullet :Int = 4
static let iceShield :Int = 8
}
this is how I set the physics body
let collisionShape = SCNPhysicsShape(node: node, options: nil)
self.physicsBody = SCNPhysicsBody(type: .dynamic, shape: collisionShape)
self.physicsBody?.categoryBitMask = self.categoryMask
self.physicsBody?.contactTestBitMask = self.collisionMask
self.physicsBody?.collisionBitMask = self.collisionMask
I use self because it is the physics body of a custom class that inherit from SCNNode, collisionMask and categoryMask are setted in the constructor using the struct above.
In the didBeginContact I want to print something but nothing happens. I already setted the SCNPhysicsContactDelegate to
sceneView.scene.physicsWorld.contactDelegate
sceneView is ARSCNView.
I correctly see the shape of the physicsBody with
SCNDebugOptionShowPhysicsShape
Why is this happening ?
Upvotes: 1
Views: 2374
Reputation: 3554
Your nodes don't interact with each other because they are in different categories.
Here is how the collsionBitMask
works according to the documentation:
When two physics bodies contact each other, a collision may occur. SceneKit compares the body’s collision mask to the other body’s category mask by performing a bitwise AND operation. If the result is a nonzero value, then the body is affected by the collision.
The contactBitMask
and categoryBitMask
work the same.
When SceneKit checks your physicsBody for a contact this is what happens:
object1.physicsBody.contactTestBitMask = 4 = 0100b
object2.physicsBody.categoryBitMask = 8 = 1000b
-----
(bitwise AND) 0000b = 0 -> no collision
The best way to define your categories is with an OptionSet
, Apple actually provides you with default categories in SCNPhysicsCollisionCategory
.
If you want two nodes or physicsBody's to interact they need to share at least one category. Otherwise they will not collide.
Here is how your example should probably look like:
struct CollisionCategory: OptionSet {
let rawValue: Int
static let moltenBullet = CollisionCategory(rawValue: 4)
static let iceWall = CollisionCategory(rawValue : 8)
}
Then you assign your categories like this:
class Bullet: SCNNode {
...
// The physics body-category is a bullet
self.physicsBody?.categoryBitMask = CollisionCategory.moltenBuller.rawValue
// This contacts with both other bullets and ice walls!
self.physicsBody?.contactBitMask = [CollsionCategory.moltenBullet, CollisionCategory.iceWall].rawValue
self.physicsBody?.collisionBitMask = self.physicsBody!.contactBitMask
}
Upvotes: 3