Search code examples
iosswiftsprite-kitskscene

SKScene's update function appears to not work


I'm a mega-noob to SpriteKit / iOS dev, so sorry if this is a stupid question.

What I'm trying to do is have a small game presented in a SwiftUI View. Everything works mostly perfect, except that for some reason the update() function in my GameScene class doesnt function at all.

Sprites will still animate and move as normal, but I'm not able to add any further logic to them.

For example, the following will never print out 'hello world':


class GameScene: SKScene
{
    let loam = Loam() //little sprite character class
    //sets up scene
    override func didMove(to view: SKView)
    {
        let skView = view
        //loads game scene
        let scene = SKScene(size: skView.bounds.size)
        scene.anchorPoint = CGPoint(x: 0.5, y: 0.5)
        scene.backgroundColor = UIColor(red: 0.9412, green: 0.8274, blue: 0.7372,alpha: 0.5)
    
        scene.addChild(loam.loam)
        skView.presentScene(scene)
    }
    //called before each frame is rendered
    override func update(_ currentTime: TimeInterval)
    {
        print("hello world")
    }
}

Am I using update() wrong? Is there some sort of clash between SwiftUI's SpriteView and SKScene?

Edit: I've found that removing

skView.presentScene(scene)

allows update() to work- but then it doesn't render any sprites / animations.


Solution

  • didMove(to view: SKView) is called when your GameScene is presented in an SKView, so your code is presenting another SKScene (which is not GameScene), as soon as GameScene is presented, and you have added the Loam sprite to this new scene.

    Whatever is responsible for calling update didn't even get a chance to call your GameScene's update method, before you told it to present a new SKScene. As a result, that new scene's update is called instead.

    Now you should understand why removing skView.presentScene causes your GameScene's update to be called. And since you added Loam to the new scene, which is now not presented, you don't see it.

    You should not need to create a new scene at all. You are already in one. Just add Loam to self:

    anchorPoint = CGPoint(x: 0.5, y: 0.5)
    backgroundColor = UIColor(red: 0.9412, green: 0.8274, blue: 0.7372,alpha: 0.5)
    addChild(loam.loam)