Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can't programmatically trigger segue in SpriteKit, using Xcode 8 and Swift 3

I'm making a game in Xcode 8 using SpriteKit and have been having a very difficult time programmatically triggering a segue. I have gone into "Main.storyboard" and made a segue between my "GameViewController" and "MenuViewController" given it the identifier "toMenu".

Failed Attempt #1

Within my GameScene.swift file I have added the following code to the update function.

override func update(_ currentTime: TimeInterval) {
    // Called before each frame is rendered

    if gameIsRunning == false{
        score = 0
        performSegue(withIdentifier: "toMenu", sender: self)
    }
    }

My goal is for the segue to trigger whenever gameIsRunning is false. However, I got the following error:

Use of unresolved identifier 'performSegue'

This is odd because performSegue is a declaration according to the API Reference.

Failed Attempt #2

I tried this solution by putting the following code into "GameScene.swift"

override func update(_ currentTime: TimeInterval) {
    // Called before each frame is rendered

    if gameIsRunning == false{
        score = 0
        GameScene(MenuViewController, animated: true, completion: nil)
    }

and I got this error:

Type of expression is ambiguous without more context

Failed Attempt #3

I found this solution very confusing but I following along anyways. I had already done step 1, so as stated in step 2, I put the following code at the bottom of "GameViewController.swift"

func goToDifferentView() {

self.performSegue(withIdentifier: "toMenu", sender: self)

}

and didn't get an error! Then I added this code to "GameViewController.swift" as instructed in step 3 of the solution

    override func viewDidLoad() {
    super.viewDidLoad()

    NotificationCenter.default.addObserver(self, selector: #selector(goToDifferentView), name: NSNotification.Name(rawValue: "toMenu"), object: nil)

Then I did step 4 of the solution so I put the following code into "MenuViewController.swift"

    override func viewDidLoad() {
    super.viewDidLoad()

    NotificationCenter.default.post(NSNotification(name: NSNotification.Name(rawValue: "toMenu"), object: nil) as Notification)

I then put the following code into my "GameScene.swift" file to actually call the function.

    override func update(_ currentTime: TimeInterval) {
    // Called before each frame is rendered

    if gameIsRunning == false{
        score = 0
        GameViewController().goToDifferentView()
    }

I then ran my game on my iPhone and everything went well until I get to the part of the game where gameIsRunning turns to false. Instead of the segue doing its thing, I got the following error:

Thread 1: Signal SIGABRT

I've gotten this error several times and it's always been that I have something hooked up incorrectly in "Main.storyboard". However, this an incredibly simple game and everything looks normal. I also didn't get this error until adding the code that I just showed you. I have confirmed several times that the segue has the identifier "toMenu". I have absolutely no clue why the segue won't work and why my Attemp #3 is causing a SIGABRT error.

like image 731
chas Avatar asked Apr 02 '17 22:04

chas


1 Answers

Since you are trying to trigger this segue in the update() function, it's being called many times per second. Try the following code and it should work.

override func update(_ currentTime: TimeInterval) {
// Called before each frame is rendered

if gameIsRunning == false{
    score = 0
    gameIsRunning = true
   NotificationCenter.default.post(NSNotification(name: NSNotification.Name(rawValue: "toMenu"), object: nil) as Notification)
}

If you were to place print("update") in your if statement you would see what I mean. Setting the gameIsRunning bool to true inside your if will insure it only gets called once.

like image 125
TheValyreanGroup Avatar answered Sep 23 '22 06:09

TheValyreanGroup