2
votes

I build an application with collision detection using delegate SCNPhysicsContactDelegate. I try to detect collision with SCNPhysicsContactDelegate delegate but it doesn't work.

what is worng !?

this is my code

let CollisionCategorySpaceMan = 1
let CollisionCategoryEnemy = 2

func physicsWorld(world: SCNPhysicsWorld, didBeginContact contact: SCNPhysicsContact) {
    if contact.nodeB.physicsBody!.categoryBitMask == CollisionCategoryEnemy {
        print("Enemy HIT!--------")
    }
}




  override func viewDidLoad() {
        super.viewDidLoad()

let mainScene = createMainScene()

        mainScene.physicsWorld.contactDelegate = self

        mainScene.physicsWorld.gravity = SCNVector3Make(0, 0, 0)



        sceneView = self.view as! GameView
        sceneView.scene = mainScene
        sceneView.delegate = self

    }

this is the enemy

func setupEnemy(){
        space = space - 300
        let football2 = SCNScene(named: "art.scnassets/k.scn")
        let football21 = football2!.rootNode.childNodeWithName("football2", recursively: false)
        football21!.name = "Enemy"
        football21!.physicsBody = SCNPhysicsBody(type: .Dynamic, shape: nil)
        football21!.physicsBody!.categoryBitMask = CollisionCategoryEnemy
        football21!.physicsBody!.collisionBitMask = CollisionCategorySpaceMan
        football21!.position = SCNVector3(x: 0, y: 0, z: Float(space))
        sceneView.scene!.rootNode.addChildNode(football21!)
    }

and this is the hero

func createMainScene() -> SCNScene {
        let scene = SCNScene(named: "art.scnassets/football.scn")
        spaceManNode = scene!.rootNode.childNodeWithName("football", recursively: false)

        spaceManNode!.physicsBody = SCNPhysicsBody(type: .Dynamic, shape: nil)
        spaceManNode!.physicsBody!.categoryBitMask = CollisionCategorySpaceMan
        spaceManNode!.physicsBody!.contactTestBitMask = CollisionCategoryEnemy
        spaceManNode.name = "SpaceMan"

        setupLighting(scene!)
        setupCameras(scene!)

        return scene!
    }
2
have you checked wether or not the didBeginContact gets at least called? Who guarantees you that nodeB is of CollisionCategoryEnemy, not nodeA?luk2302
i try both none worked :'(Ahmed Safadi
It looks like you haven't set the collisionBitMask on your spaceManNode.James P

2 Answers

2
votes

Starting with iOS 9, you have to explicitly set the "contactTestBitMask" of your physicsBody to get contact notifications. Looks like that's missing from setupEnemy(). Collisions in my game worked fine in iOS 8 but stopped working on iOS 9, until I found this post: Why Contact Delegate isn't called in SceneKit?

Hope this helps!

0
votes

In this case I found 2 missing lines:

Your enemy goal or what ever should look like this...

physicsBody?.categoryBitMask = PhysicsCategory.enemy // your enemy category (lets say 1)
physicsBody?.collisionBitMask = PhysicsCategory.player (with what can report collision lets say 2

Your hero:

physicsBody?.categoryBitMask = PhysicsCategory.player  // the category is 2
physicsBody?.collisionBitMask = PhysicsCategory.enemy | PhysicsCategory.ball // can report collision with 1 and 3        
physicsBody?.contactTestBitMask = PhysicsCategory.enemy | PhysicsCategory.ball // when hitTest performed detect collision with 1 and 3

Hope this helps, Regards