1

I keep getting "fatal error: unexpectedly found nil while unwrapping an Optional value" in the following code

let ballCategoryName =  "ball"


class GameScene: SKScene, SKPhysicsContactDelegate {
    override func didMoveToView(view: SKView) {

    let borderBody = SKPhysicsBody(edgeLoopFromRect: self.frame)
    borderBody.friction = 0
    self.physicsBody = borderBody


    let ball = childNodeWithName(ballCategoryName) as! SKSpriteNode
    ball.position = CGPointMake(self.size.width / 2, self.size.height / 2)
    ball.physicsBody?.dynamic = true
    ball.physicsBody = SKPhysicsBody(circleOfRadius: ball.size.height / 2)
    ball.physicsBody!.applyImpulse(CGVector(dx: 2.0, dy: -2.0))

    self.addChild(ball)

the Error Appears at "let ball = childNodeWithName(ballCategoryName) as! SKSpriteNode" Wondering if someone could help me out here on why this keeps appearing

  • 2
    Not sure what you are asking here. Obviously there is no child node with the `ballCategoryName` you are passing in? – hnh Jul 19 '16 at 21:43
  • @hnh I'm new to this type of code so I'm a little confused. what needs to be done to add childNode? sorry if this sounds stupid – Jonathan Burnett Jul 19 '16 at 21:49
  • Without looking at childNodeWithName, it is really harder to tell what is going wrong. – ldindu Jul 19 '16 at 21:57
  • Possible duplicate of [What does "fatal error: unexpectedly found nil while unwrapping an Optional value" mean?](http://stackoverflow.com/questions/32170456/what-does-fatal-error-unexpectedly-found-nil-while-unwrapping-an-optional-valu) – JAL Jul 19 '16 at 22:19

3 Answers3

1

You have to create that ball as a node. You can make a node like so:

let ball = SKSpriteNode(imageNamed: "fileimage.png")

and then add it to the scene.

The problem is that you're creating that ball from nowhere. You won't find anything below if you haven't created that scene yet. That child doesn't exist.

childNodeWithName(ballCategoryName) as! SKSpriteNode

Farini
  • 923
  • 1
  • 18
  • 35
1

The issue is you are force casting unsafely on this line:

let ball = childNodeWithName(ballCategoryName) as! SKSpriteNode

The method childNodeWithName() returns either a sprite kit node or nil (SKSpriteNode?). the exclamation point in: as! SKSpriteNode means you are certain this return is not nil and you want to cast it as a non-optional SKSpriteNode. It seems you have hit a case where childNodeWithName(.. returned nil so the casting failed and your app crashed.

You can unwrap the optional in a variety of ways, just for example here is what your code would look like if you used if let:

if let ball = childNodeWithName(ballCategoryName) {
    ball.position = CGPointMake(self.size.width / 2, self.size.height / 2)
    ball.physicsBody?.dynamic = true
    ball.physicsBody = SKPhysicsBody(circleOfRadius: ball.size.height / 2)
    ball.physicsBody!.applyImpulse(CGVector(dx: 2.0, dy: -2.0))
    self.addChild(ball) 
}

note that in this example if childNodeWithName(ballCategoryName) returns nil the code within the body of the if clause will not run at all.

see the apple docs for a pretty comprehensive explanation of all the ways you might unwrap optional values.

Alternately as other answers have indicated you can instantiate ball as a non-optional instance of SKSpriteNode using let ball = SKSpriteNode(imageNamed: "something.png")

Tucker Sherman
  • 459
  • 7
  • 17
0

You should replace this

let ball = childNodeWithName(ballCategoryName) as! SKSpriteNode

with this

let ball = SKSpriteNode(imageNamed: "YOUR_IMAGE_NAME")

I also suggest you reading the SpriteKit Programming Guide.

Luca Angeletti
  • 58,465
  • 13
  • 121
  • 148