错误:场景 <SCNScene:> 在另一个场景 (<SCNScene: >) 的渲染回调中被修改。这是不允许的,可能会导致崩溃

问题描述 投票:0回答:1

我正在尝试从一个场景过渡到另一个场景以进行快速游戏。我仍在学习,并对我的代码中出现的任何明显问题表示歉意。

这是一款带有 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
swift 3d scnscene scnview scnscenerenderer
1个回答
0
投票

我可以通过添加 gamePlaying 布尔变量并根据使用的场景将其设置为 true 或 false 来解决此问题。

在我的渲染器函数中,我将一些物理类别分配给第一个场景中的节点,当我将这段代码放入由 gamePlaying 布尔值触发的 if 语句中时,错误消失了。

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.