Ostatnio zapytałem o numer question, który miał dość oczywistą odpowiedź. Nadal pracuję nad tym samym projektem i napotykam inny problem. Muszę zaimplementować jedną logikę ramek, a protokół SCNSceneRendererDelegate
działał idealnie dobrze na iOS, ale w systemie OSX funkcja renderer
nie uruchamia się. Stworzyłem mały przykładowy projekt ilustrujący mój problem. Składa się on z zestawu sceny w widoku serii ujęć i następującego kodu w klasie ViewController
:SceneKit SCNSceneRendererDelegate - funkcja renderer nie nazywa się
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
}
}
Wszystko czego chcę to po prostu przesunąć sześcian z każdej klatki. Ale nic się nie dzieje. Dziwne jest to, że po ustawieniu sceneView.allowsCameraControl
na true
, funkcja renderer
jest wywoływana za każdym razem, gdy klikam lub przeciągam na ekranie (co ma sens, ponieważ wymaga aktualizacji widoku na podstawie kątów kamery). Ale chciałbym, żeby nazywał się każdy kadr.
Czy wystąpił błąd, którego nie widzę lub czy jest to błąd w moim Xcode?
Edit: Próbowałem postępując zgodnie z instrukcjami w odpowiedzi poniżej i teraz mają następujący kod dla 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
}
}
oraz klasę 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
}
}
Jednak jest wciąż nie działa. Co ja robię źle?
EDIT: ustawienie sceneView.loops = true poprawki opisanego problemu
Dokładnie! Też to wymyśliłem, ale zapomniałem zaktualizować moją odpowiedź. – Nico
W takim przypadku wydaje się, że jest to odpowiedź, która powinna zostać przyjęta. –