Reputation: 128
So I am creating a game and I just want to detect a collision between the player node and a bullet fired by an enemy. So I have set the proper parameters and the categoryBitMask and the contactTestBitMask for each of the player and bullets.
By implementing the didBegin and didEnd functions I want to execute some code when the collision begins and ends. The problem is that when I build and run the project, the physics subsystem moves the bullet around the player instead of though the player. This is because the isDynamic property is set too true for either the player, bullet, or both. Obviously, the first thing to try is to set the isDynamic property to false; however, when I do this the is no callback when a collision occurs, and the didBegin / didEnd function are not executed.
Does anyone have any ideas on how to fix this?
The code for the set up of the player and bullet physics bodies; as well as the didBegin function is below for your reference
playerNode!.physicsBody = SKPhysicsBody(rectangleOf: CGSize(width: playerNode!.size.width/2, height: playerNode!.size.height/2)) //sets the physics body for the player
playerNode!.physicsBody!.isDynamic = false //we dont want the physics to be simulated by the subsystem
playerNode!.physicsBody!.affectedByGravity = false
playerNode!.physicsBody!.pinned = false
playerNode!.physicsBody!.allowsRotation = false
playerNode!.physicsBody!.categoryBitMask = PhysicsCategory.Player
playerNode!.physicsBody!.contactTestBitMask = PhysicsCategory.Bullet
self.bullet?.physicsBody = SKPhysicsBody(circleOfRadius: bullet!.size.width * 0.5)
self.bullet?.physicsBody?.isDynamic = true
self.bullet?.physicsBody?.pinned = false
self.bullet?.physicsBody?.allowsRotation = false
self.bullet?.physicsBody?.affectedByGravity = false
self.bullet?.physicsBody?.categoryBitMask = PhysicsCategory.Bullet
self.bullet?.physicsBody?.contactTestBitMask = PhysicsCategory.Player
func didBegin(_ contact: SKPhysicsContact) {
let collision = contact.bodyA.categoryBitMask | contact.bodyB.categoryBitMask
if collision == PhysicsCategory.Player | PhysicsCategory.Bullet {
print("There was a collision with the player and a bullet")
}
}
//Defines the physics category for the game
struct PhysicsCategory {
static let None: UInt32 = 0
static let Player: UInt32 = 0b1
static let Bullet: UInt32 = 0b10
}
Upvotes: 0
Views: 81
Reputation: 8134
The bullet is ‘moving around’ the player instead of through it because you have collisions turned on. All physics bodies collide with all others by default, whereas by default there are no contacts registered between physics bodies.
The first thing to do is to turn off collisions between the player and the bullet and vice-versa whilst leaving all other collisions unaffected:
playerNode.physicsBody?.collisionBitMask &= ~physicsCategory.bullet
bullet.physicsBody?.collisionBitMask &= ~physicsCategory.player
Edit: my step-by-step guide for collisions and contacts: https://stackoverflow.com/a/51041474/1430420
A guide to collision and contactTest bit masks: https://stackoverflow.com/a/40596890/1430420
Manipulating bit masks to turn individual collisions and contacts off and on. https://stackoverflow.com/a/46495864/1430420
Upvotes: 1