0

Yesterday, I posted this question from an iPad and realized that it worked out terribly. So today I post it again, hoping to get better across what my problem is. I am writing a 3D game app, using SceneKit to display the entire scene and a SpriteKit overlay to display the controls. I am about finished with the basic gaming function, and now I need to add a menu screen. At this point, to better choose the relevant aspects of development, but at a later time this will be the main menu screen to choose the different gaming options. In short: a typical menu screen. I figured I need to use the same credentials as in the game scene, as there too are the main character to see from all perspectives, the possible level (also in 3D) and then of course buttons to push in order to choose. So again, an overlay between SceneKit and SpriteKit is required, and so is a way to switch between the two scenes with different SceneKit and overlay content. But this just doesn't work the way I thought it would. And I am having a problem in figuring out why it doesn't. The switch I am trying to accomplish makes use of the 'present with transition', and it works - I can see the animation. Only afterwards, I get the 'scene is modified with in a rendering callback' console error, even though I thought the 'present'-argument would turn off the previous scene and activate the new. A second thing I don't understand, is how the SpriteKit overlay is switched from the first to the second overlay. (Of course, the menu screen has to be inserted before the game scene, but that doesn't change anything in the problem I have, which is the switch between the two.) Here is the code I am using to achieve displaying the Menu scene:

    self.sceneView.scene = MenuScene()
    self.view.addSubview(self.sceneView)
    self.spriteMenuScene = MenuOLScene(size: self.view.bounds.size)
    self.sceneView.overlaySKScene = self.spriteMenuScene
    self.sceneView.delegate = self                                                      
    self.sceneView.scene?.physicsWorld.contactDelegate = self

Then, when the 'play' button is pushed, I try to pause the active scene (& pause the skoverlay) and do a crossfade transition (and possibly erase the skoverlay to set a new one):

    let transition = SKTransition.crossFade(withDuration: 0.5)
    self.sceneView.present(MainScene(), with: transition, incomingPointOfView: nil, completionHandler: {
        MainScene().isPaused = false})

And, as I mentioned, I get the error that 'it is not allowed to modify a scene etc. and may lead to crash', which does happen soon afterwards. I never got to the point to set the new skoverlay.

Now, I am desperately seeking help to describe a stable way to accomplish this standard-requirement of any 3D game. If anyone has this valuable knowledge, please share with me.

ULI
  • 41
  • 7
  • A thing that just came to my mind is that, whereas the menu screen is set up from viewDidLoad(), the switch of the scenes happens from the renderer delegate. But what other way could there be (since the game entirely runs on the delegate loop after the set up of the screen is done)? – ULI May 26 '20 at 17:44
  • I was doing similar and finally just went to UIKit over the top of scenekit. In my case, I wasn't doing that much with the overlay anyways - may be that could work for you. It was a lot easier. 2 cents – Voltan May 28 '20 at 20:01

0 Answers0