最近,我问了一个问题,其中有一个很明显的答案。我仍在同一个项目上,遇到另一个问题。我需要实现每帧逻辑,并且该SCNSceneRendererDelegate协议在iOS上工作得很好,但是在OSX上,该renderer功能未触发。我创建了一个小示例项目来说明我的问题。它由情节提要中的Scene Kit视图和ViewController该类中的以下代码组成:
SCNSceneRendererDelegate
renderer
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每当我点击或在屏幕上拖动(这是有道理的,因为它需要更新基于摄像机角度的视图)函数被调用。但是我希望每帧都可以调用它。
sceneView.allowsCameraControl
true
是否有我没有看到的错误,或者这是我的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可以解决上述问题
我怀疑答案取决于Querent所说的“每一帧”。Querent可能应该澄清这一点,但是无论如何我都会尝试回答,因为我就是这样。
最简单的解释可能是“无论如何都会渲染的每个帧”,但是除非多维数据集旨在用作渲染器的一种活动监视器,否则似乎不太可能是理想的,这似乎也不可能。有更好的方法。
Querent可能希望在视图的播放属性为YES时重复渲染。如果真是这样,那么答案也许很简单,就是将视图的loops属性设置为YES。最近,这为我解决了一个问题,我希望在按住键盘键的同时进行渲染。(我已经注意到将播放设置为“是”将引起对我的代表的一个呼叫。)