Nic*_*ico 8 macos scenekit 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
}
}
Run Code Online (Sandbox Code Playgroud)
我想要的只是基本上每帧移动立方体.但没有任何反应.什么是奇怪的是,当我设置sceneView.allowsCameraControl到true时,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
}
}
Run Code Online (Sandbox Code Playgroud)
和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
}
}
Run Code Online (Sandbox Code Playgroud)
但是,它仍然无法正常工作.我究竟做错了什么?
编辑:设置sceneView.loops = true修复了描述的问题
我不明白是什么导致了这个问题,但我能够复制它.但是,通过增加一个毫无意义的东西,我得到了它的工作SCNAction:
let dummyAction = SCNAction.scaleBy(1.0, duration: 1.0)
let repeatAction = SCNAction.repeatActionForever(dummyAction)
cubeNode.runAction(repeatAction)
Run Code Online (Sandbox Code Playgroud)
仅当场景"正在播放"时才会触发渲染循环(请参阅SKScene在空闲时变得无响应).我期待那个设定
sceneView.isPlaying = true
Run Code Online (Sandbox Code Playgroud)
(正如你已经做的那样)足以触发渲染回调.
我上面的代码不是解决方案.解决你的问题是一个讨厌的黑客,让你继续生活.
对于仍有问题的人,设置委托和播放变量都可以.
sceneView.delegate = self
sceneView.isPlaying = true
Run Code Online (Sandbox Code Playgroud)