Gusfat
Gusfat

Reputation: 111

unexpectedly found nil while unwrapping an Optional value - Sprite Kit

Hey guys im having a huge problem with my Sprite Kit game. Im new to it and im trying to do a kind of asteroids game just to do exercise what i learnt.

My problem is, my asteroids are infinite, they don't stop unless the player is hit. My code is the follows:

For the meteor:

  func addMeteor() {

        let bigMeteor = SKSpriteNode(imageNamed: "meteor1")

        let bigMeteorAux = bigMeteor
        let sizeX = UInt32(CGRectGetMaxX(self.frame))
        let randomX = CGFloat(arc4random_uniform(sizeX))
        var impulse : CGVector!

        bigMeteorAux.position = CGPoint(x: randomX, y: size.height + 100)
        impulse = CGVector(dx: 0, dy: -30)
        bigMeteorAux.physicsBody = SKPhysicsBody(texture: bigMeteor.texture, size: bigMeteor.size);
        bigMeteor.physicsBody?.affectedByGravity = false
        bigMeteor.physicsBody?.allowsRotation = false
        bigMeteorAux.physicsBody?.friction = 0.0
        bigMeteorAux.physicsBody!.categoryBitMask = CollisionCategoryAsteroids
        bigMeteorAux.name = "Asteroid"

        foregroundNode!.addChild(bigMeteorAux)

        bigMeteorAux.physicsBody!.applyImpulse(impulse)

    }

Im calling the function with an action:

   runAction(SKAction.repeatActionForever(
        SKAction.sequence([
            SKAction.runBlock(addMeteor),
            SKAction.waitForDuration(1.0)
            ])
        ))

Perfect until now, the game works just fine. This is the player code:

    playerNode = SKSpriteNode(imageNamed: "spaceshipv2")
    playerNode!.physicsBody = SKPhysicsBody(texture: playerNode!.texture, size: playerNode!.size);
    playerNode!.xScale = 0.5
    playerNode!.yScale = 0.5
    playerNode!.position = CGPoint(x: size.width / 2.0, y: 220.0)
    playerNode!.physicsBody!.linearDamping = 1.0
    playerNode!.physicsBody!.allowsRotation = false
    playerNode!.physicsBody?.affectedByGravity = false
    playerNode!.physicsBody!.categoryBitMask = CollisionCategoryPlayer
    playerNode!.physicsBody!.contactTestBitMask =
        CollisionCategoryAsteroids
    playerNode!.name = "Player"
    //addChild(playerNode!)
    foregroundNode!.addChild(playerNode!)

And for the last the contact func:

    func didBeginContact(contact: SKPhysicsContact) {

        var nodeB = contact.bodyB!.node!

        if nodeB.name == "Asteroid"  {

            println("Touched")
            nodeB.removeFromParent()
        }

    }

So my problem start with the nodeB, for some reason sometimes when the Asteroid hit the player this code works just fine but other times when the asteroid hit the player the game crashes and i get

fatal error: unexpectedly found nil while unwrapping an Optional value

After the program enters the contact function.

Any ideas or solution about how to fix this? Thx a lot! =)

Upvotes: 1

Views: 1163

Answers (2)

Cadin
Cadin

Reputation: 4649

I'm not sure why the node is coming up nil, but you can avoid the crash by not force unwrapping the nil values:

if let nodeB = contact.bodyB?.node?
    if nodeB.name == "Asteroid"  {
        println("Touched")
        nodeB.removeFromParent()
    }
}

Then that bit of code will only run if those optionals can be successfully unwrapped.

Upvotes: 1

Mundi
Mundi

Reputation: 80271

The crash comes from one of the two forced unwrap calls: bodyB! and node!. By writing it like this, you are asserting that you are sure they will never be nil.

The way to find the case where one of these is nil, break up the code into lines that you can check with a breakpoint.

var bodyB = contact.bodyB
if bodyB == nil {
    // breakpoint here
}
var nodeB = bodyB!.node
if nodeB == nil {
    // breakpoint here
}
if nodeB!.name = "Asteroid" // etc.

Once the code stops you can examine the objects and try to find out why they are nil and fix the problem.

Upvotes: 1

Related Questions