1
votes

I can't figure out why my collisions aren't being detected. I hope you can figure out why, because it's causing me a lot of issues and I need to learn how to do this properly. Swift, SceneKit.

Alright so as always I start out with this statement:

    override func viewDidLoad() {
    super.viewDidLoad()


    createScene()



   scene.physicsWorld.contactDelegate = self

   // This Statement.^

    motionManager = CMMotionManager()
    motionManager.startAccelerometerUpdates()


}

I want a collision to occur between a ball and box node. My box node is mainBox, and my ball is... ball.

 ball.position = SCNVector3Make(0, 1.75, 3)
    ball.geometry = ballGeometry
    ballMaterial.diffuse.contents = UIColor.greenColor()
    ballGeometry.materials = [ballMaterial]
    scene.rootNode.addChildNode(ball)
    ball.physicsBody = SCNPhysicsBody(type: .Dynamic, shape: SCNPhysicsShape(geometry: ballGeometry, options: nil))
    ball.physicsBody?.angularVelocityFactor = SCNVector3Make(0, 0, 0)
    ball.physicsBody?.angularVelocity = SCNVector4Make(0, 0, 0, 0)
    ball.name = "sphere"
    ball.physicsBody?.categoryBitMask = bodyNames.Person
    ball.physicsBody?.contactTestBitMask = bodyNames.Floor
    ball.physicsBody?.collisionBitMask = bodyNames.Floor
    ball.physicsBody?.affectedByGravity = true
    ball.addChildNode(cameraNode)


    mainBox.position = SCNVector3Make(0, -0.75, 2)
    mainBox.geometry = mainBoxGeometry
    mainBoxMaterial.diffuse.contents = UIColor.whiteColor()
    mainBox.physicsBody?.categoryBitMask = bodyNames.Floor
    mainBox.physicsBody?.contactTestBitMask = bodyNames.Person
    mainBox.physicsBody?.collisionBitMask = bodyNames.Person
    mainBox.physicsBody = SCNPhysicsBody.staticBody()
    mainBoxGeometry.materials = [mainBoxMaterial]
    mainBox.name = "floor"
    scene.rootNode.addChildNode(mainBox)

And now where the magic happens, but also where the magic isn't happening...

 func physicsWorld(world: SCNPhysicsWorld, didBeginContact contact: SCNPhysicsContact) {

    let nodeA = contact.nodeA
    let nodeB = contact.nodeB

    if nodeA.physicsBody?.categoryBitMask == bodyNames.Person && nodeB.physicsBody?.categoryBitMask == bodyNames.Floor || nodeA.physicsBody?.categoryBitMask == bodyNames.Floor && nodeB.physicsBody?.categoryBitMask == bodyNames.Person {


        print("I collided with the damn box.")

    }

}

Oh and this thing is where the bodyNames comes from.

struct bodyNames {

static let Person = 0x1 << 1
static let Floor = 0x1 << 2

}

Let me know if I need to add more code to be answered, I'd be happy to do so.

1
You're setting all the bitmasks on mainBox physicsBody before you set the physicsBody itself.James P
Very simple fix but it works properly now. Thanks. @JamesPTiptech

1 Answers

0
votes

have u checked whether didBeginContact visited or not?

if visited, check the if condition

nodeA.physicsBody?.categoryBitMask == bodyNames.Person && nodeB.physicsBody?.categoryBitMask == bodyNames.Floor || nodeA.physicsBody?.categoryBitMask == bodyNames.Floor && nodeB.physicsBody?.categoryBitMask == bodyNames.Person

if not visited at all, u have to check whether physicsBody of world, box and ball config correctly