4

When I switch to my gamescene from my menu scene, it works perfectly fine. But, when I try to go back, it is a disaster. I get: unexpectedly found nil while unwrapping an Optional value. The code for going back is:

let menuscene = MenuScene(size: self.size)
menuscene.scaleMode = scaleMode
self.view?.presentScene(menuscene)

The code that it says the error comes from is:

PlaygamebtnNode = self.childNode(withName: "PlaygamebtnNode") as! SKSpriteNode
NamelblNode = self.childNode(withName: "NamelblNode") as! SKLabelNode

This is odd because when the game launches, it is fine with this code. The error has to come from the change in views/scenes. The code for the entrie MenuScene class is:

import SpriteKit
import GameplayKit

class MenuScene: SKScene {
    var PlaygamebtnNode:SKSpriteNode!
    var NamelblNode:SKLabelNode!

    override func didMove(to view: SKView) {

        PlaygamebtnNode = self.childNode(withName: "PlaygamebtnNode") as! SKSpriteNode
        NamelblNode = self.childNode(withName: "NamelblNode") as! SKLabelNode


        PlaygamebtnNode.texture = SKTexture(imageNamed: "Playgamebtn")
    }

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {

        let touch = touches.first

        if let location = touch?.location(in: self){
            let nodesArray = self.nodes(at: location)

            if nodesArray.first?.name == "PlaygamebtnNode" {
                let transition = SKTransition.flipHorizontal(withDuration: 0.5)

                let nextScene = GameScene(size: self.size)
                self.view?.presentScene(nextScene, transition: transition)
            }
        }
    }
}

The reason this is not a ordinary found nil while unwrapping an Optional value question is because it does not show this error until I try to go back to the menu.

Donald Duck
  • 8,409
  • 22
  • 75
  • 99
Peter
  • 87
  • 7
  • Check if value exist before accesing them ( optional binding). Also, you shouldn't use forced downcaating if you are not sure it will 100% succseed. Hint: use breakpoints and see what is going on. – Whirlwind May 03 '17 at 07:17
  • @Whirlwind where might I put these breakpoint, as to me it seems this is a error when creating the view for the second time. I've tried changing the as! to as? and found that then, the nearest line is the error. – Peter May 03 '17 at 07:23
  • Put an exception breakpoint for start. Search SO about how to do that. It should take you to the line which crashes. – Whirlwind May 03 '17 at 07:26
  • After having done that, I found it is the same line: PlaygamebtnNode = self.childNode(withName: "PlaygamebtnNode") as! SKSpriteNode @Whirlwind – Peter May 03 '17 at 07:30
  • @Whirlwind I've been adding different breakpoints and testing different things. This is really a bizarre error. – Peter May 03 '17 at 08:02
  • Check what `self.childNode(withName:"PlaugamebtnNode")` returns. See if it is a `nil` or not and if it is a `SKSpriteNode` or something else. Error is simple, actually. If you can, you can upload a mvp that can reproduce the issue and upload it on github. That way, I could check directly and tell where the error is. But still, check what the method above returns. – Whirlwind May 03 '17 at 08:59
  • I understand this may be a stupid thing to not be able to figure out, but I am new to swift and spritekit. My native language is c# and this kind of error is not something we would get in visual or unity. Anyway, I will send you a github link. Thanks so much for the help, appreciate it. @Whirlwind – Peter May 03 '17 at 10:11
  • @Whirlwind here is the google drive foler: https://drive.google.com/open?id=0B0accAKJCi_MMDBkV0dBbUtvSlE – Peter May 03 '17 at 10:20
  • Okay, I'll check it out now... – Whirlwind May 03 '17 at 10:22
  • The code can't compile. LaunchScreen and MainStoryboard (which I guess you don't even use) are missing... – Whirlwind May 03 '17 at 10:27
  • I'll put it in a zip. They definitely exist. Google must not have been able to recognize those files. – Peter May 03 '17 at 10:30
  • I can add them by myself though if those are not required ? (eg you don't have any UI elements defined in storyboard) – Whirlwind May 03 '17 at 10:31
  • I don't. Just in case, https://drive.google.com/open?id=0B0accAKJCi_MbjhEakZnNWhLTzg – Peter May 03 '17 at 10:32
  • Okay, I found the problem. I will make an answer shortly. – Whirlwind May 03 '17 at 10:41
  • Note that you should follow naming conventions... Eg `playGameBtnNode` rather than `PlaygamebtnNode` because it is a variable name, not the class or protocol name. Also, `leavegamefunc()` should be `leaveGame()`. – Whirlwind May 03 '17 at 11:15

1 Answers1

3

The problem started with this line:

PlaygamebtnNode = self.childNode(withName: "PlaygamebtnNode") as! SKSpriteNode 

because as I said, self.childNode(withName:) was returning nil

The real problem however was related to this line (inside of leavegamefunc()):

let menuscene = MenuScene(size: self.size)

You have defined your PlaygamebtnNode in MenuScene.sks and you are using wrong initializer (MenuScene.init(size:)).

The solution:

 func leavegamefunc() {
        if let menuScene = MenuScene(fileNamed: "MenuScene"){
            menuScene.scaleMode = scaleMode
            self.view?.presentScene(menuScene)
        }
    }
Whirlwind
  • 14,286
  • 11
  • 68
  • 157