小编典典

SceneKit SCNSceneRendererDelegate-未调用渲染器功能

swift

最近,我问了一个问题,其中有一个很明显的答案。我仍在同一个项目上,遇到另一个问题。我需要实现每帧逻辑,并且该SCNSceneRendererDelegate协议在iOS上工作得很好,但是在OSX上,该renderer功能未触发。我创建了一个小示例项目来说明我的问题。它由情节提要中的Scene
Kit视图和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.allowsCameraControltrue时,renderer每当我点击或在屏幕上拖动(这是有道理的,因为它需要更新基于摄像机角度的视图)函数被调用。但是我希望每帧都可以调用它。

是否有我没有看到的错误,或者这是我的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可以解决上述问题


阅读 350

收藏
2020-07-07

共1个答案

小编典典

我怀疑答案取决于Querent所说的“每一帧”。Querent可能应该澄清这一点,但是无论如何我都会尝试回答,因为我就是这样。

最简单的解释可能是“无论如何都会渲染的每个帧”,但是除非多维数据集旨在用作渲染器的一种活动监视器,否则似乎不太可能是理想的,这似乎也不可能。有更好的方法。

Querent可能希望在视图的播放属性为YES时重复渲染。如果真是这样,那么答案也许很简单,就是将视图的loops属性设置为YES。最近,这为我解决了一个问题,我希望在按住键盘键的同时进行渲染。(我已经注意到将播放设置为“是”将引起对我的代表的一个呼叫。)

2020-07-07