Search code examples
iosswiftsprite-kitskphysicsbodyskphysicscontact

Collision Bit Mask Hero passes right through EVERY thing, even the Ground


I am trying to avoid collisions between Hero and Coins, but not between Hero and Grass Ground. As soon as I apply a Collision Bit Mask to Hero, my Hero passes right through EVERY thing. I want it to pass through the Coins but not through the Grass Ground. Here is the code, any ideas?

let HEROCATEGORY: UInt32 = 0x1 << 1;
let GROUNDCATEGORY: UInt32 = 0x1 << 2;
let FIRECATEGORY: UInt32 = 0x1 << 3;
let COINCATEGORY: UInt32 = 0x1 << 4;
let NUMBERCATEGORY: UInt32 = 0x1 << 5;

heroSprite.physicsBody!.categoryBitMask = HEROCATEGORY;
heroSprite.physicsBody!.collisionBitMask = 0x10000000;
heroSprite.physicsBody!.contactTestBitMask = GROUNDCATEGORY | FIRECATEGORY | COINCATEGORY | NUMBERCATEGORY;

grassGround.physicsBody!.categoryBitMask = GROUNDCATEGORY;
grassGround.physicsBody!.collisionBitMask = 0x01000000;

coinSprite.physicsBody!.categoryBitMask = COINCATEGORY;
coinSprite.physicsBody!.contactTestBitMask = HEROCATEGORY;
coinSprite.physicsBody!.collisionBitMask = 0x10000000;

Solution

  • If hero has to detect collision with only the ground, then hero's collission bit mask should be

    heroSprite.physicsBody?.collisionBitMask = GROUNDCATEGORY
    

    To detect collision with ground and something else, you should use the OR | operator to combine both categoryBitMasks

     heroSprite.physicsBody?.collisionBitMask = GROUNDCATEGORY | SOMETHINGCATEGORY
    

    The contactTestBitMask is used to get a callback on contact between the two bodies. We get a callback when both objects share the same space. It doesn't handle collisions.

    I think what you need is contact detection with fire and coins and collision detection with ground. So just set collision bit mask of heroSprite to GROUNDCATEGORY like in my first code snippet.

    let HEROCATEGORY: UInt32 = 0x1 << 1
    let GROUNDCATEGORY: UInt32 = 0x1 << 2
    let FIRECATEGORY: UInt32 = 0x1 << 3
    let COINCATEGORY: UInt32 = 0x1 << 4
    let NUMBERCATEGORY: UInt32 = 0x1 << 5
    
    heroSprite.physicsBody!.categoryBitMask = HEROCATEGORY
    heroSprite.physicsBody!.collisionBitMask = GROUNDCATEGORY // changed
    heroSprite.physicsBody!.contactTestBitMask = GROUNDCATEGORY | FIRECATEGORY | COINCATEGORY | NUMBERCATEGORY
    
    grassGround.physicsBody!.categoryBitMask = GROUNDCATEGORY
    grassGround.physicsBody!.collisionBitMask = HEROCATEGORY
    
    coinSprite.physicsBody!.categoryBitMask = COINCATEGORY
    coinSprite.physicsBody!.contactTestBitMask = HEROCATEGORY