Recentemente ho chiesto un question che aveva una risposta piuttosto ovvia. Sto ancora lavorando allo stesso progetto e mi sto imbattendo in un altro problema. Devo implementare la logica per frame e il protocollo SCNSceneRendererDelegate
ha funzionato perfettamente su iOS, ma su OSX, la funzione renderer
non sta funzionando. Ho creato un piccolo progetto di esempio per illustrare il mio problema. Si compone di un kit di scena vista in storyboard e seguente codice nella classe ViewController
:SceneKit SCNSceneRendererDelegate - funzione di rendering non chiamata
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
}
}
Tutto quello che voglio è quello di spostare sostanzialmente il cubo con ogni fotogramma. Ma non succede nulla. La cosa strana è che quando imposto lo sceneView.allowsCameraControl
su true
, la funzione renderer
viene chiamata ogni volta che clicco o trascino sullo schermo (il che ha senso perché è necessario aggiornare la vista in base agli angoli della telecamera). Ma vorrei che fosse chiamato ogni frame.
C'è un errore che non vedo o si tratta di un bug nel mio Xcode?
Edit: Ho provato seguendo le istruzioni riportate nella risposta qui sotto e ora hanno il seguente codice per la 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
}
}
e una classe 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
}
}
Tuttavia, è continua a non funzionare. Che cosa sto facendo di sbagliato?
Modifica: impostazione sceneView.loops = true risolve il problema descritto
Esattamente! Ho capito anche io, ma ho dimenticato di aggiornare la mia risposta. – Nico
In tal caso, sembra che questa sia la risposta che dovrebbe essere accettata. –