草庐IT

swift - SceneKit SCNSceneRendererDelegate - 未调用渲染器函数

coder 2023-07-17 原文

我最近问了一个question这有一个非常明显的答案。我仍在从事同一个项目并遇到另一个问题。我需要实现每帧逻辑,SCNSceneRendererDelegate 协议(protocol)在 iOS 上工作得很好,但在 OSX 上,renderer 函数没有触发。我创建了一个小示例项目来说明我的问题。它由 Storyboard中的 Scene Kit View 和 ViewController 类中的以下代码组成:

import Cocoa
import SceneKit

class ViewController: NSViewController, SCNSceneRendererDelegate {

    @IBOutlet weak var sceneView: SCNView!

    let cubeNode = SCNNode()

    override func viewDidLoad() {

        super.viewDidLoad()

        let scene = SCNScene()

        let sphere = SCNSphere(radius: 0.1)
        sphere.firstMaterial!.diffuse.contents = NSColor.yellowColor()
        let sphereNode = SCNNode(geometry: sphere)
        scene.rootNode.addChildNode(sphereNode)

        let cube = SCNBox(width: 0.2, height: 0.2, length: 0.2, chamferRadius: 0)
        cube.firstMaterial!.diffuse.contents = NSColor.greenColor()
        cubeNode.geometry = cube
        cubeNode.position = SCNVector3(1,0,0)
        scene.rootNode.addChildNode(cubeNode)

        let cameraNode = SCNNode()
        cameraNode.camera = SCNCamera()
        cameraNode.position = SCNVector3(2, 1, 2)
        let constraint = SCNLookAtConstraint(target: cubeNode)
        cameraNode.constraints = [constraint]
        scene.rootNode.addChildNode(cameraNode)

        sceneView.scene = scene
        sceneView.backgroundColor = NSColor(red: 0.5, green: 0, blue: 0.3, alpha: 1)
        sceneView.allowsCameraControl = true

        sceneView.delegate = self
        sceneView.playing = true

    }

    func renderer(renderer: SCNSceneRenderer, updateAtTime time: NSTimeInterval) {
        cubeNode.position.x += 0.1
    }
}

我只想在每一帧移动立方体。但是没有任何反应。奇怪的是,当我将 sceneView.allowsCameraControl 设置为 true 时,每当我在屏幕上单击或拖动时,都会调用 renderer 函数(这是有道理的,因为它需要根据摄像机角度更新 View )。但我希望每一帧都调用它。

是否有我没有看到的错误,或者这是我的 Xcode 中的错误?

编辑: 我已尝试按照以下答案中的说明进行操作,现在 ViewController 的代码如下:

import Cocoa
import SceneKit

class ViewController: NSViewController {

    @IBOutlet weak var sceneView: SCNView!
    let scene = MyScene(create: true)

    override func viewDidLoad() {

        super.viewDidLoad()

        sceneView.scene = scene
        sceneView.backgroundColor = NSColor(red: 0.5, green: 0, blue: 0.3, alpha: 1)
        sceneView.allowsCameraControl = true

        sceneView.delegate = scene
        sceneView.playing = true

    }

}

还有一个 MyScene 类:

import Foundation
import SceneKit

final class MyScene: SCNScene, SCNSceneRendererDelegate {

    let cubeNode = SCNNode()

    convenience init(create: Bool) {
        self.init()

        let sphere = SCNSphere(radius: 0.1)
        sphere.firstMaterial!.diffuse.contents = NSColor.yellowColor()
        let sphereNode = SCNNode(geometry: sphere)
        rootNode.addChildNode(sphereNode)

        let cube = SCNBox(width: 0.2, height: 0.2, length: 0.2, chamferRadius: 0)
        cube.firstMaterial!.diffuse.contents = NSColor.greenColor()
        cubeNode.geometry = cube
        cubeNode.position = SCNVector3(1,0,0)
        rootNode.addChildNode(cubeNode)

        let cameraNode = SCNNode()
        cameraNode.camera = SCNCamera()
        cameraNode.position = SCNVector3(2, 1, 2)
        let constraint = SCNLookAtConstraint(target: cubeNode)
        cameraNode.constraints = [constraint]

        rootNode.addChildNode(cameraNode)
    }

    @objc func renderer(aRenderer: SCNSceneRenderer, updateAtTime time: NSTimeInterval) {
        cubeNode.position.x += 0.01
    }
}

但是,还是不行。我做错了什么?

编辑:设置 sceneView.loops = true 修复了所描述的问题

最佳答案

我不明白是什么导致了这个问题,但我能够复制它。不过,我通过添加无意义的 SCNAction 让它工作:

let dummyAction = SCNAction.scaleBy(1.0, duration: 1.0)
let repeatAction = SCNAction.repeatActionForever(dummyAction)
cubeNode.runAction(repeatAction)

渲染循环仅在场景正在“播放”时触发(参见 SKScene becomes unresponsive while being idle )。我希望这样的设置

    sceneView.isPlaying = true

(正如您已经在做的那样)足以触发渲染回调。

我上面的代码不是解决方案。解决您的问题并让您继续生活是一种令人讨厌的技巧。

关于swift - SceneKit SCNSceneRendererDelegate - 未调用渲染器函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35390959/

有关swift - SceneKit SCNSceneRendererDelegate - 未调用渲染器函数的更多相关文章

随机推荐