Home > database >  Avoiding collision in spriteKit on iOS while maintaining contact
Avoiding collision in spriteKit on iOS while maintaining contact

Time:05-05

I have 2 physicsBodies and don't want them to collide (ie they must pass through each other) but still want to be notified in case of contact, however when setting the collisionBitMask to 0, the contact event is not called anymore. What am I doing wrong ?

let stoneCategory  : UInt32 = 0x1 << 1
let birdCategory  : UInt32 = 0x1 << 2

physicsWorld.contactDelegate = self

stoneNode = SKSpriteNode(imageNamed: "Stone");
self.addChild(stoneNode)
stoneNode.physicsBody = SKPhysicsBody(rectangleOf: stoneNode.size);
stoneNode.physicsBody?.categoryBitMask = stoneCategory
stoneNode.physicsBody?.contactTestBitMask = birdCategory
stoneNode.physicsBody?.collisionBitMask = 0

birdNode = SKSpriteNode();
<...Set texture...> 
self.addChild(birdNode)
birdNode.physicsBody = SKPhysicsBody(rectangleOf: birdNode.size);
birdNode.physicsBody?.categoryBitMask = birdCategory
birdNode.physicsBody?.contactTestBitMask = stoneCategory
birdNode.physicsBody?.collisionBitMask = 0
birdNode.physicsBody?.isDynamic = false;

func didBegin(_ contact: SKPhysicsContact) {
    print("Contact between " contact.bodyA.node!.name! " and " contact.bodyB.node!.name!); // --> Never called
}

CodePudding user response:

You might have a different problem in your code elsewhere, because this is working for me. The bodies do not collide and the contact happens.

Sample playground code:

import PlaygroundSupport
import SpriteKit

class GameScene: SKScene, SKPhysicsContactDelegate {
    
    var stoneNode: SKShapeNode!
    var birdNode: SKShapeNode!
    
    override func didMove(to view: SKView) {
        
        let stoneCategory  : UInt32 = 0x1 << 1
        let birdCategory  : UInt32 = 0x1 << 2

        physicsWorld.contactDelegate = self

        stoneNode = SKShapeNode(circleOfRadius: 30)
        stoneNode.name = "stone"
        stoneNode.position = CGPoint(x: 0, y: 100)
        addChild(stoneNode)
        stoneNode.physicsBody = SKPhysicsBody(circleOfRadius: 30)
        stoneNode.physicsBody?.categoryBitMask = stoneCategory
        stoneNode.physicsBody?.contactTestBitMask = birdCategory
        stoneNode.physicsBody?.collisionBitMask = 0

        birdNode = SKShapeNode(circleOfRadius: 40)
        birdNode.name = "bird"
        birdNode.position = CGPoint(x: 0, y: -100)
        addChild(birdNode)
        birdNode.physicsBody = SKPhysicsBody(circleOfRadius: 40);
        birdNode.physicsBody?.categoryBitMask = birdCategory
        birdNode.physicsBody?.contactTestBitMask = stoneCategory
        birdNode.physicsBody?.collisionBitMask = 0
        birdNode.physicsBody?.isDynamic = false;
    }
    
    func didBegin(_ contact: SKPhysicsContact) {
        print("Contact between " contact.bodyA.node!.name! " and " contact.bodyB.node!.name!); // --> Never called
    }
}

// Load the SKScene from 'GameScene.sks'
let sceneView = SKView(frame: CGRect(x:0 , y:0, width: 640, height: 480))
if let scene = GameScene(fileNamed: "GameScene") {
    // Set the scale mode to scale to fit the window
    scene.scaleMode = .aspectFill
    
    // Present the scene
    sceneView.presentScene(scene)
}

PlaygroundSupport.PlaygroundPage.current.liveView = sceneView

And in the console, when the first body drops, being affected by gravity, it's printed:

Contact between stone and bird

  • Related