I have two different fixed SKPhysicsBody in an SKScene. The only difference between the two is their categoryBitMask. One has a categoryBitMask of 512, the other 1024.
static const u_int32_t kWallCategory = 0x1 << 9; //512
static const u_int32_t kStructureCategory = 0x1 << 10; //1024
In my program, I have a standard contact handler called from -(void)didBeginContact:(SKPhysicsContact *)contact
that begins:
-(void)handleContact:(SKPhysicsContact*)contact {
SKPhysicsBody *bodyA = contact.bodyA;
SKPhysicsBody *bodyB = contact.bodyB;
int type1 = contact.bodyA.categoryBitMask;
int type2 = contact.bodyB.categoryBitMask;
In my program, I need to determine the contact vector between a dynamic body and one of the two fixed bodies. In order to do so, I access the contactNormal property of the SKPhysicsContact
CGVector c = contact.contactNormal;
What I noticed, though, was that the contact vectors were inconsistent and I determined this was because sometimes bodyA of the SKPhysicsContact was the fixed body, sometimes bodyA was the dynamic body.
For example, when a bullet (dynamic body) hits a building (fixed body) from the left, I want the contact vector to be (-1,0)
each time. Currently, the contact vector is sometimes (-1,0)
(from the left) and sometimes (1,0)
(from the right) all depending on which body contact.bodyA
is.
My question: given all else being equal (physics properties, etc.) what determines what is bodyA and what is bodyB in an SKPhysicsContact?
After tinkering with several aspects of each
SKPhysicsBody
(mass, friction, categoryBitmask, etc), I've ascertained that the determination betweenSKPhysicsContact.bodyA
andSKPhysicsContact.bodyB
is based solely on when the SKPhysicsBody is added to the sceneAn example to highlight the difference:
SKPhysicsBody *bullet
hitsSKPhysicsBody *building
from the left.Case 1: If
*building
was added to the scene before*bullet
, theSKPhysicsContact.contactNormal
is:(-1,0)
BecauseSKPhysicsContact.bodyA
is*building
, therefore the contact vector is where the*building
is being contacted from (i.e. the left).Case 2: If
*building
was added to the scene after*bullet
, theSKPhysicsContact.contactNormal
is:(1,0)
BecauseSKPhysicsContact.bodyA
is now*bullet
, therefore the contact vector is where the*bullet
is being contacted from (i.e. the right).Problem
Because
*bullet
and*building
entities are added at various times in my program, I needed to implement a method in which I always knew whatSKPhysicsContact.bodyA
andSKPhysicsContact.bodyB
were and, more importantly, a way to keep theSKPhysicsContact.contactNormal
consistent.Solution
Determine the
SKPhysicsBody
that you need to determine where collisions are coming from and set thephysicsBody.categoryBitMask
Then, in the contact handler: