Ich verwende SceneKit und erlaube Benutzern, das, was sie sehen, in einer Kugel zu drehen, indem sie eine Schwenkgeste verwenden. Das funktioniert gut - außer, ich möchte die Kugel leicht in die Richtung der Schwenkbewegung drehen lassen, um ein bisschen reaktiver zu wirken.SceneKit - Hinzufügen von Drift zu einer Kugel, die mit einer Schwenkbewegung gedreht wurde
Hier ist mein Setup für die Szene:
// Create scene
let scene = SCNScene()
sceneView.scene = scene
let panRecognizer = UIPanGestureRecognizer(target: self,
action: #selector(ViewController.handlePanGesture(_:)))
sceneView.addGestureRecognizer(panRecognizer)
//Create sphere
let sphere = SCNSphere(radius: 50.0)
// sphere setup
sphereNode = SCNNode(geometry: sphere)
sphereNode!.position = SCNVector3Make(0,0,0)
scene.rootNode.addChildNode(sphereNode!)
// Create camera
let camera = SCNCamera()
// camera setup
cameraNode = SCNNode()
cameraNode!.camera = camera
cameraNode!.position = SCNVector3Make(0, 0, 0)
cameraOrbit = SCNNode()
cameraOrbit!.addChildNode(cameraNode!)
scene.rootNode.addChildNode(cameraOrbit!)
let lookAtConstraint = SCNLookAtConstraint(target: sphereNode!)
lookAtConstraint.gimbalLockEnabled = true
cameraNode!.constraints = [lookAtConstraint]
sceneView.pointOfView = cameraNode
Und hier ist, wie die pan Geste zur Zeit (mit freundlicher Genehmigung von SCNCamera limit arcball rotation) behandelt wird:
let translation = sender.translationInView(sender.view!)
let widthRatio = Float(translation.x)/Float(sender.view!.frame.size.width) + lastWidthRatio
let heightRatio = Float(translation.y)/Float(sender.view!.frame.size.height) + lastHeightRatio
self.cameraOrbit?.eulerAngles.y = Float(-2 * M_PI) * widthRatio
self.cameraOrbit?.eulerAngles.x = Float(-M_PI) * heightRatio
if (sender.state == .Ended) {
lastWidthRatio = widthRatio
lastHeightRatio = heightRatio
}
Ich bin mir nicht sicher, wo in beginnen Hinzufügen einer leichten fortgesetzten Drehbewegung. Vielleicht eine physicsBody
hinzufügen und Kraft anwenden? Vielleicht animiert die Änderung in eulerAngles
?
Ich landete etwas ähnliches - danke! Mein Problem ist nun, dass der 'lastRatio'-Wert jetzt deaktiviert ist, weil die letzte Ruheposition der Kugel sich weiter gedreht hat als das letzte Mal, als dieser Wert gesetzt wurde. Wenn der Benutzer also die nächste Schwenkgeste ausführt, "springt" die Kamera zu der Position, bevor die Drift gestartet wurde, während die "eulerAngles" zurückgesetzt werden. Wenn Sie irgendwelche Gedanken dazu haben, bin ich ganz Ohr. –
Hmm, versuchen Sie vielleicht, einen 'closer'-Handler zu' runAction 'hinzuzufügen, der die lastRatio-Werte erneut aktualisiert, wenn die Aktion abgeschlossen ist? –
@AndyHeard Ich habe das versucht, aber es funktioniert nicht und ich verstehe wirklich nicht warum. Hier ist mein Code-Schnipsel '' 'lastWidthRatio + = (((-velocity.x * 0.001) * 2)/sender.view.frame.size.width);' '' –