如何在 SKScene 中引用我的 UIViewController?
How to do a reference of my UIViewController in the SKScene?
我需要将我的 UIViewController 作为我的 GameScene 的 属性。
所以在调用 presentScene 之前,我用 UIViewController 设置了 属性。
我的 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
}
}
}
}
}
我的游戏场景class:
class GameScene: SKScene, SKPhysicsContactDelegate {
// MARK: Properties
var gameViewController:GameViewController!
override func sceneDidLoad() {
print(self.gameViewController) // -> CRASH
//DO SOME STUFF
}
}
我遇到了这个崩溃:
fatal error: unexpectedly found nil while unwrapping an Optional value
编辑 1
所以我尝试使用:
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
}
但是物理世界不再起作用了。我的崩溃消失了,但是物理世界坏了。
在我的控制台中:
--->GameViewController - viewDidLoad()<---
--->GameScene - sceneDidLoad()<---
--->GameScene - sceneDidLoad()<---
--->GameScene - didMove(to:)<---
--->GameViewController - viewWillAppear<---
--->GameViewController - viewDidAppear<---
在 ViewDidLoad 上使用 GameSceneView Controller:
if let scene = SKScene(fileNamed: "GameScene") {
currentGame = scene as! GameScene
currentGame.gameViewController = self
}
那么你们就可以互相参考了。
sceneDidLoad
函数在您设置对 gameViewController 的引用之前被调用。您应该改用 SKScene didMoveToView
函数。
override func didMove(to view: SKView) {
print(self.gameViewController)
}
您可以在 Xcode 中设置断点(在您的 gameScene 和 gameViewController 中)并查看事件的时间。顺便说一句,更好的做法是使用协议来实现 delegate pattern
,而不是像这样使用具体的引用。
您忘记添加到 GameViewController
,在此代码之后:
// Get the SKScene from the loaded GKScene
if let sceneNode = scene.rootNode as! GameScene? {
行:
sceneNode.gameViewController = self
另外,在你的场景中class你应该使用:
override func didMove(to view: SKView) {
因为 sceneDidLoad()
方法(现在在 iOS10 中)等同于 UIKit 中的 viewDidLoad()
,但是你的视图尚未呈现场景。
我需要将我的 UIViewController 作为我的 GameScene 的 属性。 所以在调用 presentScene 之前,我用 UIViewController 设置了 属性。
我的 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
}
}
}
}
}
我的游戏场景class:
class GameScene: SKScene, SKPhysicsContactDelegate {
// MARK: Properties
var gameViewController:GameViewController!
override func sceneDidLoad() {
print(self.gameViewController) // -> CRASH
//DO SOME STUFF
}
}
我遇到了这个崩溃:
fatal error: unexpectedly found nil while unwrapping an Optional value
编辑 1
所以我尝试使用:
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
}
但是物理世界不再起作用了。我的崩溃消失了,但是物理世界坏了。
在我的控制台中:
--->GameViewController - viewDidLoad()<---
--->GameScene - sceneDidLoad()<---
--->GameScene - sceneDidLoad()<---
--->GameScene - didMove(to:)<---
--->GameViewController - viewWillAppear<---
--->GameViewController - viewDidAppear<---
在 ViewDidLoad 上使用 GameSceneView Controller:
if let scene = SKScene(fileNamed: "GameScene") {
currentGame = scene as! GameScene
currentGame.gameViewController = self
}
那么你们就可以互相参考了。
sceneDidLoad
函数在您设置对 gameViewController 的引用之前被调用。您应该改用 SKScene didMoveToView
函数。
override func didMove(to view: SKView) {
print(self.gameViewController)
}
您可以在 Xcode 中设置断点(在您的 gameScene 和 gameViewController 中)并查看事件的时间。顺便说一句,更好的做法是使用协议来实现 delegate pattern
,而不是像这样使用具体的引用。
您忘记添加到 GameViewController
,在此代码之后:
// Get the SKScene from the loaded GKScene
if let sceneNode = scene.rootNode as! GameScene? {
行:
sceneNode.gameViewController = self
另外,在你的场景中class你应该使用:
override func didMove(to view: SKView) {
因为 sceneDidLoad()
方法(现在在 iOS10 中)等同于 UIKit 中的 viewDidLoad()
,但是你的视图尚未呈现场景。