在SwiftUI中使用SceneKit时如何访问SCNSceneRendererDelegate方法?

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

我通过遵循Mehdi为这个问题提供的解决方案,将SceneKit与SwiftUI一起使用:

SwiftUI - how to add a Scenekit Scene

通常,当创建一个SceneKit项目时,实现渲染器方法就像在GameViewController文件中添加以下扩展并实现每个渲染器方法一样容易:

extension GameViewController: SCNSceneRendererDelegate {
  // 2
  func renderer(renderer: SCNSceneRenderer, updateAtTime time: NSTimeInterval) {
    // 3
    doWhatever()
  }
}

但是在使用SwiftUI时,我们使用结构而不是类(请参见上面的链接问题),因此我们不能简单地添加扩展名,因为Xcode会抱怨:

Non-class type 'ScenekitView" cannot conform to class protocol 'NSObjectProtocol'
Non-class type 'ScenekitView' cannot conform to class protocol 'SCNSceneRendererDelegate'

对此有什么解决方案?

swift swiftui scenekit
1个回答
0
投票

找到此答案的解决方案:

SwiftUI – Passing data from SwiftUIView to SceneKit

在Andy问题的下半部分,他描述了如何使用协调器来实现委托方法。为方便起见,在此处复制:

struct ScenekitView: NSViewRepresentable {

    @Binding var showStats: Bool
    let sceneView = SCNView(frame: .zero)
    let scene = SCNScene(named: "art.scnassets/ship.scn")!

    func makeCoordinator() -> Coordinator {
        Coordinator(self)
    }

    final class Coordinator: NSObject, SCNSceneRendererDelegate {
        var control: ScenekitView

        init(_ control: ScenekitView) {
            self.control = control
        }

        func renderer(_ renderer: SCNSceneRenderer,
               updateAtTime time: TimeInterval) {

            control.sceneView.showsStatistics = control.showStats

            for i in 0...255 {
                control.sceneView.backgroundColor = NSColor(
                                  red: CGFloat(arc4random_uniform(UInt32(i))),
                                green: CGFloat(arc4random_uniform(UInt32(i))),
                                 blue: CGFloat(arc4random_uniform(UInt32(i))),
                                alpha: 1.0)
            }
        }
    }

    func scnScene(stat: Bool, context: Context) -> SCNView {
        sceneView.scene = scene
        sceneView.showsStatistics = stat
        sceneView.delegate = context.coordinator
        return sceneView
    }

    func makeNSView(context: Context) -> SCNView {
        scnScene(stat: true, context: context)
    }

    func updateNSView(_ uiView: SCNView, context: Context) { }
}
© www.soinside.com 2019 - 2024. All rights reserved.