SKPhysicsContact detect the contact not expecting

Here is my code:


func didBegin(_ contact: SKPhysicsContact) {

  print("contact.bodyA.categoryBitMask:::\(contact.bodyA.categoryBitMask)")
  print("contact.bodyA.contactTestBitMask:::\(contact.bodyA.contactTestBitMask)")
  print("contact.bodyA.isDynamic:::\(contact.bodyA.isDynamic)")
  print("contact.bodyB.categoryBitMask:::\(contact.bodyB.categoryBitMask)")
  print("contact.bodyB.contactTestBitMask:::\(contact.bodyB.contactTestBitMask)")
  print("contact.bodyB.isDynamic:::\(contact.bodyB.isDynamic)")
and I got the result:

contact.bodyA.categoryBitMask:::1 contact.bodyA.contactTestBitMask:::9 contact.bodyA.isDynamic:::true contact.bodyB.categoryBitMask:::5 contact.bodyB.contactTestBitMask:::8 contact.bodyB.isDynamic:::false

I found the contact nodes are not collected by its categoryBitMask and contactTestBitMask. I mean A's categoryBitMask not match B's contactTestBitMask, but their contact can be detect.

Somebody tell me why, and how can I optimize the SKPhysicsContact.

Replies

body A category = 0001, contact = 1001


body B category = 0101, contact = 1000


(Body A category) bitwise-& (body B contact) = 0000, would not flag collision


(Body B category) bitwise-& (body A contact) = 0001, flags collision


According to the documentation, if either comparison gives a nonzero result, you'll get a collision notification.

https://developer.apple.com/documentation/spritekit/skphysicsbody/1519781-contacttestbitmask


If you don't want that notification, you have to make sure that body B's category mask does not overlap with body A's contact mask.

but my confuse is

contact.bodyA.categoryBitMask = Uint32(1) contactTestBitMask = Uint32(9)

contact.bodyB.categoryBitMask = Uint32(5) contactTestBitMask = Uint32(8)


Their collision can be detect, and I am sure the unnecessary collision detect drops my game fps down.

Uint32(5) bitwise-& Uint32(9) = Uint32(1). Because that result isn't 0, it's notifying you of the collision.

If you don't want that notification, you have to either change B's category bitmask or A's contact bitmask.

The fact that the overlap between A's category and B's contact is 0 doesn't matter, since it notifies you if either result isn't 0.