I'm creating a game which will need to use a lot of collision detection and i'm only learning about it today.
Now I have two SKSpriteNodes
but one is a child of an SKNode
. The SKSpriteNode
without a parent is called character
and the sprite with the parent is called buildingStructure
.
Now character
's category is static const uint32_t playerCategory = 0x1 << 20;
and buildingStructure
's category is _buildingStructureCategory = 0x1 << 0;
. buildingStructure
's category is set in another class map.m
through a @property
.
The variables pass over correctly to another class called main.m
(which is where the character
category is set). I create character
with a method, setting his physics body, position and so on.
character
's properties
character.name = @"character";
character.size = CGSizeMake(250, 400);
character.zPosition = 500;
character.position = CGPointMake(self.scene.size.width/2, self.scene.size.height/2+200);
character.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:character.size];
character.physicsBody.restitution = 0;
character.physicsBody.density = 0.1;
character.physicsBody.allowsRotation = NO;
character.physicsBody.categoryBitMask = playerCategory;
character.physicsBody.collisionBitMask = categoryBitManager.buildingStructureCategory;
buildingStructure
's properties
buildingStructure.name = @"buildingStructure";
buildingStructure.position = CGPointMake(building.position.x, building.position.y);
buildingStructure.size = CGSizeMake(500, 400);
buildingStructure.physicsBody.dynamic = NO;
buildingStructure.physicsBody.categoryBitMask = _buildingStructureCategory;
On the other hand buildingStructure
doesn't have a set physicsBody
because I want character
to pass through buildingStructure
but I also want it to detect when character
is 'on top' of buildingStructure
to perform an action.
Since buildingStructure
doesn't have a defined physicsBody
is this what's causing didBeginContact:contact
to not recognise the collision contact?
The physicsBody property of an SKNode (or subclass of) is nil by default. Yes give the buildingStructure a physics body and correctly configure it to achieve the desired behaviour.
To get the desired behaviour between two physics bodies, first understand that there are 'collisions' and there are 'contacts'. SKPhysicsBody has two properties named collisionBitMask and contactTestBitMask.
For collisionBitMask the default value is 0xFFFFFFFF (all bits set), and for contactTestBitMask the default value is 0x00000000 (all bits cleared). You can see that by defaults every physics body will collide with others but there will be no contact.
A collision is where you want the physics simulation to affect the body in question, where a contact is where you want to be notified so you can do something. So this will call didBeginContact:
I suggest setting the collisionBitMask for both bodies to 0 (so their physics is not affected and pass through one another). Then set the contactTestBitMask property of character to that of the building like this-
character.physicsBody.contactTestBitMask = categoryBitManager.buildingStructureCategory;