SwiftUI+SpriteKit踩坑-调用SKScene对象函数不生效

问题重现

点击按钮,调用GameScene对象的函数,分别是向左跑动,停止,向右跑动。
SwiftUI代码如下(GameScene.swift代码略):

var scene: GameScene  {
    let scene = SKScene(fileNamed: "GameScene") as! GameScene
    scene.scaleMode = .aspectFill
    return scene
}

struct ContentView: View {
    
    var body: some View {
        ZStack {
            SpriteView(scene: scene)
            
            VStack {
                Spacer()
                HStack {
                    Button("<<<") {
                        scene..runAnim(.L)
                    }
                    Button("xxx") { scene.runToStopAnim() }
                    Button(">>>") {scene.runAnim(.R)}
                }
            }
        }
    }
}

排查经过

发现点击按钮后,界面没有出现跑动动画。
在GameScene的runAnim函数打上断点,运行后发现断点触发,表明确实是调用到函数了。
又在GameScene里重写touchesBegan函数,在里面直调用用runAnim函数,运行,点击界面,有发生动画了。
可以确定 GameScene的代码是没有问题的。
于是猜想,是不是因为存在某些机制,SwiftUI不能直接调用SKScene里面的函数?
网上一顿搜索,“Swiftui 如何控制 SpriteView” 之类的问题,下载了一些Demo,找到的资料,实现方式都是,从SwiftUI传递变量到SKScene里面,然后SKScene在update函数里判断变量并更新界面。
差点就掉进坑里了。
午休后,看到一个stackoverflow的一个回答[这里],发现自己犯了一个跟该问题一样的低级错误。

解决

原来一不注意,我把 scene 写成了计算属性,导致每次使用scene时,都是重新创建对象。
正确写法是:

var scene: GameScene = {
    let scene = SKScene(fileNamed: "GameScene") as! GameScene
    scene.scaleMode = .aspectFill
    return scene
}()

实践证明,是可以直接在SwiftUI里面调用SpriteKit对象函数的。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章