As far as I'm aware the default for Physics bodies is to bounce off each other when they hit each other until you set their collisionBitMask to an equal number.
However, I'm having a huge issue accomplishing what seems like it should be very simple because of collisionBitmasks I believe.
let RedBallCategory : UInt32 = 0x1 << 1
let GreenBallCategory: UInt32 = 0x1 << 2
let RedBarCategory : UInt32 = 0x1 << 3
let GreenBarCategory : UInt32 = 0x1 << 4
let WallCategory : UInt32 = 0x1 << 5
greenBall.physicsBody?.categoryBitMask = GreenBallCategory
greenBall.physicsBody?.contactTestBitMask = RedBarCategory
greenBall.physicsBody?.collisionBitMask = GreenHealthCategory
redBall.physicsBody?.categoryBitMask = RedBallCategory
redBall.physicsBody?.contactTestBitMask = GreenBarCategory
redBall.physicsBody?.collisionBitMask = RedHealthCategory
let borderBody = SKPhysicsBody(edgeLoopFromRect: self.frame)
self.physicsBody = borderBody
self.physicsBody?.friction = 0
borderBody.contactTestBitMask = RedBallCategory | GreenBallCategory
borderBody.categoryBitMask = WallCategory
So here I've got my 2 balls and my border body. I can get collision detection which I want, but when I add the border body's category bit mask, it allows the balls to both go through and off the screen, which I don't want.
I also want the balls to bounce off each other, but only when I comment out one of the ball's categoryBitMasks do they bounce. Otherwise they go through each other.
That makes absolutely no sense to me because each of these items has a different collisionbitmask. I also had it sometimes where setting all the numbers equal to 5 would allow everything to pass through each other, but then setting it all to 6 would allow everything to hit each other.
How exactly do collision bitmasks work and is there a proper way to manage a lot of crisscrossing collision rules?
You can't get desired behaviour because you haven't set category, contact and collision bit masks properly. Here is an example on how you can set this to work:
I would recommend you to read docs about categoryBitMask which is a mask that defines which categories a physics body belongs to:
contactTestBitMask - A mask that defines which categories of bodies cause intersection notifications with a current physics body.
collisionBitmask - A mask that defines which categories of physics bodies can collide with this physics body.
So basically, to set up all these, you should ask your self something like:
Okay, I have a green ball, and a red ball , and wall objects on the scene. Between which bodies I want collisions to occur, or when I want to register contacts? I want a green and a red ball to collide with each other and to collide against the walls. Not a problem. I will first set up categories properly, and then I will set collision bit masks like this:
Now, I want to detect when some contacts occur (in
didBeginContact
: method)... But I don't want to get notified about all possible contacts, but rather to be notified just about contacts between balls (contacts between balls and a wall will be ignored). So lets setcontactTestBitMasks
to achieve this:And that's it. The important thing is when you not using contact detection, you should not set
contactTestBitMask
. This is because of performance reasons. If you don't need collision detection, and you are interested only in detecting contacts, you can setcollisionBitMask = 0
.Important:
Make sure you have set physics world's contact delegate in order to use
didBeginContact
anddidEndContact
methods:Hope this helps a bit.
Just want to add something here, that if the contact or collision are not able to work properly, you need to make sure that you assign the physicsBody shape first before applying the bitMasks.
Example of not working bitmask:
And working one:
Anyway probably just a newbie mistake, but I'd share here cause this is what caused mine not to work properly.