我正在尝试从一个场景过渡到另一个场景以进行快速游戏。我仍在学习,并对我的代码中出现的任何明显问题表示歉意。
这是一款带有 Blender 动画的 3D 游戏。
我有一个 GameViewController 和一个 GameController。到目前为止,游戏一直运行,但我无法在没有错误消息的情况下进行转换。
当我尝试转换到新场景(由“gameOver”逻辑提示)时,新场景会显示,但出现此错误:错误:场景
这是我的代码 - 我已对其进行编辑以仅显示相关部分,但如果您需要更多信息,请告诉我。
我不知道是否需要在某处创建新的 GameOverViewController 和/或 GameOverController 来为新场景实例化新的渲染器函数? 如果您有任何建议,请告诉我,非常感谢您的帮助!
// GameViewController.swift
import UIKit
import SceneKit
import SpriteKit
protocol GameControllerDelegate: AnyObject {
func decreaseScore()
func gameOver2()
}
var score = 0
class GameViewController: UIViewController, SCNPhysicsContactDelegate, GameControllerDelegate {
var gameView: SCNView {
return self.view as! SCNView
}
var gameController: GameController!
override func viewDidLoad() {
super.viewDidLoad()
self.gameController = GameController(sceneRenderer: gameView)
self.gameController.gameDelegate = self
gameView.scene!.physicsWorld.contactDelegate = self
}
func gameOver2() {
gameScene?.isPaused = true
let transition = SKTransition.doorsOpenVertical(withDuration: 1.0)
gameView.present(gameOverScene!, with: transition, incomingPointOfView: nil, completionHandler: {
print("completionhandler")
})
}
}
// GameController.swift
import SceneKit
import UIKit
import SpriteKit
var gameScene = SCNScene(named: "Art.scnassets/Game.scn")
var endgameScene = SCNScene(named: "Art.scnassets/GameOver.scn")
class GameController: NSObject, SCNSceneRendererDelegate {
var scene: SCNScene
let sceneRenderer: SCNSceneRenderer
var gameViewController: GameViewController!
var gameView: GameController!
lazy var gamePlaying = true
weak var gameDelegate: GameControllerDelegate?
init(sceneRenderer renderer: SCNSceneRenderer) {
sceneRenderer = renderer
scene = gameScene!
super.init()
sceneRenderer.delegate = self
sceneRenderer.scene = gameScene
}
func renderer(_ renderer: SCNSceneRenderer, didSimulatePhysicsAtTime time: TimeInterval) {
camera?.physicsBody?.angularVelocityFactor = SCNVector3(0, 0, 0)
camera?.position = SCNVector3(x: -7, y: ((pwet?.presentation.position.y)! + 4), z: 60)
if gamePlaying == true {
if score < 0 {
DispatchQueue.main.async {
self.gamePlaying = false
self.gameDelegate?.gameOver2()
}
}
}
}
编辑以回复反馈评论:
我添加了一些打印语句来查看哪个场景被引用:
当我运行 viewDidLoad (第一个场景运行)时,它显示这个场景:
viewDidLoad - gameView.scene = <SCNScene: 0x600003701440>
当我到达 gameOver 函数时,它会尝试暂停该函数:
gameOver2 = gameScene.isPaused = Optional(<SCNScene: 0x600003701440>)
并运行这个:
completionhandler gameView.present = gameOverScene = Optional(<SCNScene: 0x600003772dc0>)
错误消息这样引用它们:
Error: Scene <SCNScene: 0x600003701440> is modified within a rendering callback of another scene (<SCNScene: 0x600003772dc0>). This is not allowed and may lead to crash
我可以通过添加 gamePlaying 布尔变量并根据使用的场景将其设置为 true 或 false 来解决此问题。
在我的渲染器函数中,我将一些物理类别分配给第一个场景中的节点,当我将这段代码放入由 gamePlaying 布尔值触发的 if 语句中时,错误消失了。