This code crashes because secondBody
is not associated with a node.
func didBegin(_ contact: SKPhysicsContact) {
// Set vars to hold bodies
var firstBody: SKPhysicsBody
var secondBody: SKPhysicsBody
// Sort bodies
if contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask {
firstBody = contact.bodyA
secondBody = contact.bodyB
} else {
firstBody = contact.bodyB
secondBody = contact.bodyA
}
// Handle different contacts
if firstBody.categoryBitMask == BallBitMask && secondBody.categoryBitMask == TileBitMask {
didBallTileHit(tile: secondBody.node!) // Code crashes here :(
}
...
}
1) Aside from setting a physics body to nil
, what would cause a physics body to lose association with a node in SpriteKit?
2) How can a physics body even exist without a node in the first place?
An SKSPhysicsBody is an object in itself and perfectly capable of being created yet not associated with an SKSpriteNode (although perhaps not of much use :-) )
In your
didBallTileHit()
, do youremoveFromParent()
any of the nodes? If so, this is probably the cause of your crash in that Sprite-Kit has generated multiple collisions between 2 objects and is callingdidBegin()
several times for the 2 nodes. If you then go and remove one of the nodes in the 1st call todidBegin()
, it won't be there for the 2nd and subsequent calls.The way to handle it (you can't get sprite-kit to NOT call didBegin multiple times in some circumstances) is to make sure that your contact code accommodates this and that handling the contract multiple times does not cause a problem (such as adding to the score multiple times, removing multiple lives, trying to access a node or physicsBody that has been removed etc).
For more detail and possible solutions, see this answer : https://stackoverflow.com/a/44384390/1430420