我希望 bobNode 查看用户在屏幕上点击的位置。我正在努力旋转 bobNode。我正在记录点击位置,当我点击时它会起作用。我从来没有得到 print("Angle: "+ String(describing: angle))
。唯一一次 print("Testing Renderer function")
是在应用程序加载时打印 11 次,之后就不再打印了。我想我只是对旋转 bobNode 的概念感到困惑。如果我做错了,有人可以向我解释如何去做。
代码:
var sceneView: SCNView! // for now
var bobNode: SCNNode!
var lastTouch: CGPoint? = nil
let bobScene = SCNScene(named: "art.scnassets/man.scn")!
func start(){
let scene = SCNScene()
sceneView.delegate = self
bobNode = bobScene.rootNode.childNode(withName: "Player", recursively: true)!
bobNode.scale = SCNVector3(x: 0.15, y: 0.15, z: 0.15)
bobNode.eulerAngles = SCNVector3(x: GLKMathDegreesToRadians(75), y: 0.0, z: GLKMathDegreesToRadians(180))//Don't use rotaion THAT shit is retarded
scene.rootNode.addChildNode(bobNode)
sceneView.scene = scene
let camera = SCNCamera()
let cameraNode = SCNNode()
cameraNode.camera = camera
cameraNode.position = SCNVector3(x: bobNode.position.x, y: bobNode.position.y, z: 10.0)
scene.rootNode.addChildNode(cameraNode)
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
handleTouches(touches: touches)
}
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
handleTouches(touches: touches)
}
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
handleTouches(touches: touches)
}
private func handleTouches(touches: Set<UITouch>) {
for touch in touches {
let touchLocation = touch.location(in: sceneView)
lastTouch = touchLocation
print("Touch: " + String(describing: lastTouch))
}
}
func renderer(_ renderer: SCNSceneRenderer, didSimulatePhysicsAtTime time: TimeInterval) {
if let _ = bobNode {
updatePlayer()
}
}
func updatePlayer() {
print("Testing Renderer function")
if let touch = lastTouch {
let currentPosition = bobNode.position
let angle = atan2(CGFloat(currentPosition.y) - CGFloat(touch.y), CGFloat(currentPosition.x) - CGFloat(touch.x)) + CGFloat(Double.pi)
print("Angle: " + String(describing: angle))
let rotateAction = SCNAction.rotateBy(x: 0.0, y: angle, z: 0.0, duration: 0)
bobNode.runAction(rotateAction)
}
}
最佳答案
最简单的解决方案是将 SCNLookAtConstraint 添加到 bobNode
。
当您创建 SCNLookAtConstraint 时,它需要一个目标 SCNNode 并且 SceneKit 将在每一帧将 bobNode
旋转到给定的目标。
我们称它为 targetNode
(大概没有几何体),它位于场景 3D 空间中用户点击位置的正下方。它的位置需要随着用户点击的变化而更新。
当然,用户点击表示为屏幕坐标空间中的 2D 点,需要将其转换为场景的 3D 空间。
这可以通过您的 SCNView 的 unprojectPoint:
方法来完成。
你必须给它传递一个 SCNVector3 参数,它保存着屏幕点击的 X 和 Y 坐标,它的 Z 分量在 0.0 和 1.0 之间,代表 2D 点在场景 3D 空间中投影的深度(在 near 之间)和相机的远剪裁平面)。我猜你需要它接近 0.0。
设置
// Create the look-at constraint
SCNLookAtConstraint lookAtConstr = [SCNLookAtConstraint lookAtConstraintWithTarget:];
// Set to bobNode's .constraints property
bobNode.constraints = @[lookAtConstr];
在每一帧
// tapLocation is the screen tap location from UIEvent
SCNVector3 tapPosition = SCNVector3Make(tapLocation.x, tapLocation.y, 0.0);
// unproject from 2D screen to 3D scene space
SCNVector3 targetNodePosition = [scnView unprojectPoint:tapPosition];
// Update the targetNode position
targetNode.position = targetNodePosition;
关于ios - 将 SCNNode 旋转到用户点击的位置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43623130/