Reputation: 1
I am trying to transition from one scene to another for my swift game. I am still learning and apologize for any blatant issues with my code.
This is a 3D game with animations from Blender.
I have a GameViewController and a GameController. The game has been working so far, but I am not able to get the transition without the error message.
When I try to transition to a new scene (prompted by a "gameOver" logic), the new scene shows up, but I get this error: Error: Scene <SCNScene:> is modified within a rendering callback of another scene (<SCNScene: >). This is not allowed and may lead to crash.
Here is my code - I've edited it to show only the relevant parts but please let me know if you need more information.
I don't know if I need to be creating a new GameOverViewController and / or GameOverController somewhere, to instantiate a new renderer function for the new scene? Please let me know if you have any suggestions, I appreciate your help!
// 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()
}
}
}
}
edited to respond to feedback comment:
I added a couple of print statements to see which scene is being referenced where:
when I run viewDidLoad (first scene runs), it shows this scene:
viewDidLoad - gameView.scene = <SCNScene: 0x600003701440>
when I get to the gameOver function, it tries to pause that one:
gameOver2 = gameScene.isPaused = Optional(<SCNScene: 0x600003701440>)
and runs this one:
completionhandler gameView.present = gameOverScene = Optional(<SCNScene: 0x600003772dc0>)
The error message references them as such:
Error: Scene <SCNScene: 0x600003701440> is modified within a rendering callback of another scene (<SCNScene: 0x600003772dc0>). This is not allowed and may lead to crash
Upvotes: 0
Views: 50
Reputation: 1
I was able to resolve this issue by adding a gamePlaying boolean variable and setting it to true or false depending on which scene was in use.
In my renderer function I was assigning some Physics Categories to nodes from my first scene, and when I placed that piece of code inside an if statement triggered by the gamePlaying boolean, the error went away.
So basically my renderer function now includes this if statement:
if gamePlaying is true: do the things that should only happen when the gamePlaying scene is being rendered;
if gamePlaying is false: do the other things
Upvotes: 0