I need to have my UIViewController as a property of my GameScene. So before calling presentScene, I set the property with the UIViewController.
My UIViewController class:
class GameViewController: UIViewController {
var scene:GameScene!
override func viewDidLoad() {
super.viewDidLoad()
if let scene = GKScene(fileNamed: "GameScene") {
// Get the SKScene from the loaded GKScene
if let sceneNode = scene.rootNode as! GameScene? {
self.scene=sceneNode
// Set the scale mode to scale to fit the window
sceneNode.scaleMode = .aspectFill
// Present the scene
if let view = self.view as! SKView? {
sceneNode.gameViewController = self //SET THE PROPERTY
view.presentScene(sceneNode)
view.ignoresSiblingOrder = true
view.showsPhysics = true
view.showsFPS = true
view.showsNodeCount = true
}
}
}
}
}
My GameScene class:
class GameScene: SKScene, SKPhysicsContactDelegate {
// MARK: Properties
var gameViewController:GameViewController!
override func sceneDidLoad() {
print(self.gameViewController) // -> CRASH
//DO SOME STUFF
}
}
I get this crash:
fatal error: unexpectedly found nil while unwrapping an Optional value
EDIT 1
So I tried to use:
override func didMove(to view: SKView) {
super.didMove(to: view)
self.physicsWorld.contactDelegate = self
self.physicsBody!.categoryBitMask = ColliderType.DeviceBounds.rawValue
//ALL MY INIT CODE
}
override func sceneDidLoad() {
super.sceneDidLoad()
//NOTHING HERE
}
But the physic world doesn't work anymore. My crash disappears, but the physic world is broken.
In the console I have:
--->GameViewController - viewDidLoad()<---
--->GameScene - sceneDidLoad()<---
--->GameScene - sceneDidLoad()<---
--->GameScene - didMove(to:)<---
--->GameViewController - viewWillAppear<---
--->GameViewController - viewDidAppear<---
The sceneDidLoad
function gets called before you have set the reference to gameViewController. You should use the SKScene didMoveToView
function instead.
override func didMove(to view: SKView) {
print(self.gameViewController)
}
You could set breakpoints in Xcode (in your gameScene and in gameViewController) and see the timing of events. As an aside, it is a better practice to implement the delegate pattern
using protocols, rather than using concrete references like this.