Reputation: 502
I wrote the following code to detect collisions between the player, a wall and a npc:
struct PhysicsCategories{
static let player: UInt32 = 0x1 << 1
static let npc: UInt32 = 0x1 << 2
static let wall: UInt32 = 0x1 << 3
static let all: UInt32 = 0xFFFFFFFF
}
these are the setting for the player:
self.physicsBody!.categoryBitMask = Constants.PhysicsCategories.player
self.physicsBody!.collisionBitMask = Constants.PhysicsCategories.npc | Constants.PhysicsCategories.wall
self.physicsBody!.contactTestBitMask = Constants.PhysicsCategories.npc
these are the settings for the wall:
tileNode.physicsBody!.categoryBitMask = Constants.PhysicsCategories.wall
tileNode.physicsBody!.collisionBitMask = Constants.PhysicsCategories.player | Constants.PhysicsCategories.npc
these are the settings for the npc:
npc.physicsBody!.categoryBitMask = Constants.PhysicsCategories.npc
npc.physicsBody!.collisionBitMask = Constants.PhysicsCategories.wall | Constants.PhysicsCategories.player | Constants.PhysicsCategories.npc
npc.physicsBody!.contactTestBitMask = Constants.PhysicsCategories.player
I want the npc to collide with the wall and the player. The player should collide with the npc and the wall. The result is that the player can collide with the wall and the npc, but the npc can only collide with the player and goes through the walls..
Has anyone an idea what i'm doing wrong here? The npc is walking randomly around the scene, is the collisionbitmask behavior affected by this?
EDIT: If I set the dynamic property of the npc to true, it works. But I don't want the npc to be dynamic because I don't want that the player can push the npc away. Why is it only working when the npc is dynamic?
Upvotes: 1
Views: 336
Reputation: 8134
If you don't want the player to be able to push the npc around, don't mess around with the dynamic
property, just switch off collisions between the npc and the player:
npc.physicsBody!.collisionBitMask &= ~Constants.PhysicsCategories.player
This will set the bit representing the player's category to 0 in npc's collisionBitMask
without affecting any of npc's other collision settings.
or don't set them in the first place. Change:
npc.physicsBody!.collisionBitMask = Constants.PhysicsCategories.wall | Constants.PhysicsCategories.player | Constants.PhysicsCategories.npc
to
npc.physicsBody!.collisionBitMask = Constants.PhysicsCategories.wall | Constants.PhysicsCategories.npc
So npc no longer collides with player - this means that if the 2 come into contact, npc will be unaffected by player and carry on moving completely unaffected by the collision. The contactTestbitMask
is still set however, so your code will be notified of the collision.
The player, however, will bounce off the npc unless you also do the same for the player:
player.physicsBody!.collisionBitMask &= ~Constants.PhysicsCategories.npc
When you say :
The npc is walking randomly around the scene, is the collisionbitmask behavior affected by this?
Do you mean it's just bouncing off things and bouncing around the screen, or is there a problem with your movement code? If the former, then do as Kod said and set restitution to 0. From https://developer.apple.com/documentation/spritekit/skphysicsbody :
The restitution property determines how much energy a body maintains during a collision—its bounciness.
Upvotes: 2
Reputation: 332
If I understood correctly, you want the player and the NPC to "bounce off the walls", but not bounce off each other. The solution would be to not set their collisionBitMasks to each other‘s categoryBitMasks, but only their contactTestBitMasks.
As to why the NPC needs to be dynamic to bounce off the walls: One participant must be dynamic for a collision to show effect: the one that bounces off.
Upvotes: 1