0

I am getting the node attached to a contact body (SKPhysicsBody), in a function called while detecting a contact between to SKSpriteNode. Sometimes, I get an error because it can not get the node attached to the contact body, so I test if there's a node to avoid that type of error. But a warning tells me it will never return false. I've not had anymore error like this since I test that but I'm not sure if it works well or if it can still happen. Do you have any idea?

//The actual code
func didBegin(_ contact: SKPhysicsContact) {
    if (contact.bodyA.categoryBitMask == enemyCategory) && (contact.bodyB.categoryBitMask == shootCategory){ //test if it is the contact with I want to catch
        let shootNode = contact.bodyB.node, shootNode != nil { // I test if there's a node attached to the enemyShootNode but it's supposed never to return false
            let enemyNode = contact.bodyA.node, enemyNode != nil { // I test if there's a node attached to the shootNode but it's supposed never to return false
                let enemySKNode = enemyNode as? SKSpriteNode
                let shootSKNode = shootNode as? SKSpriteNode
                // code
            }
        }
    }
}

   // The code with error
func didBegin(_ contact: SKPhysicsContact) {
    if (contact.bodyA.categoryBitMask == enemyCategory) && (contact.bodyB.categoryBitMask == shootCategory){
        let shootNode = contact.bodyB.node!
        let enemyNode = contact.bodyA.node! // The error occurs here : "fatal error: unexpectedly found nil while unwrapping an Optional value"
        let enemySKNode = enemyNode as? SKSpriteNode
        let shootSKNode = shootNode as? SKSpriteNode
     }
}
gamer12
  • 23
  • 5
  • I would recommend searching better on SO and taking the time to learn the plight others have had, you will learn a lot that way. https://stackoverflow.com/questions/36655903/unexpectedly-found-nil-skspritenode , https://stackoverflow.com/questions/31057866/when-projectile-hits-two-monsters-the-didbegincontact-method-crashes-i-know-w , https://stackoverflow.com/questions/30030784/hit-fatal-error-unexpectedly-found-nil-while-unwrapping-an-optional-value-lldb , https://stackoverflow.com/questions/34188183/why-my-node-calls-didbegincontact-method-when-its-not-in-the-scene – Knight0fDragon Oct 26 '17 at 15:05
  • Possible duplicate of [Receiving an error when nodes make contact](https://stackoverflow.com/questions/44895717/receiving-an-error-when-nodes-make-contact) – Knight0fDragon Oct 26 '17 at 15:05
  • I would recommend reading the solution to this question as well. Typically this has to do with the optional `?` variable getting assigned a value of `nil`.I would check your inits for your variables or add some breakpoints in the code to see where a `nil` value might come from. https://stackoverflow.com/questions/32170456/what-does-fatal-error-unexpectedly-found-nil-while-unwrapping-an-optional-valu?rq=1 – KSigWyatt Oct 26 '17 at 15:49
  • @KSigWyatt, I can tell you where his `nil` is coming from. He is removing a `node` during the physics phase of the update cycle. the physics phase retains the physics body that it needs to use, but it does not retain the `node`. Since `SKPhysicsbody.node` is a `weak reference`, `node` becomes `nil`. – Knight0fDragon Oct 26 '17 at 15:58
  • @Knight0fDragon Ah, that makes sense then. – KSigWyatt Oct 26 '17 at 16:02
  • Yep - sounds like the old '`didBegin` called multiple times for single collision' – Steve Ives Oct 29 '17 at 09:06

1 Answers1

0

Thanks for your advices, the error indeed comes from the SKPhysics property (the didBegin function is called several times) but I didn't manage to fix. Although I corrected the way I was checking if a sprite was here, and there are no more warnings or errors so I suppose it works well :

func didBegin(_ contact: SKPhysicsContact) {
    if (contact.bodyA.categoryBitMask == enemyCategory) && (contact.bodyB.categoryBitMask == shootCategory) || (contact.bodyA.categoryBitMask == shootCategory) && (contact.bodyB.categoryBitMask == enemyCategory){
        if var shootNode = contact.bodyB.node{
            if var enemyNode = contact.bodyA.node{
                // If the enemyNode and the shootNode don't respectively correspond to 
                if contact.bodyA.categoryBitMask == shootCategory {
                    shootNode = contact.bodyA.node!
                    enemyNode = contact.bodyB.node!
                }
                let enemySKNode = enemyNode as? SKSpriteNode
                let shootSKNode = shootNode as? SKSpriteNode
            }
        }
    }
}
gamer12
  • 23
  • 5