Marcel
Marcel

Reputation: 502

collisionBitMask doesn't work

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

Answers (2)

Steve Ives
Steve Ives

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

Lennart Wisbar
Lennart Wisbar

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

Related Questions