SceneKit 中的第三人称相机
3rd Person Camera in SceneKit
我需要将 SCNCamera
附加到 SCNNode
以便每当节点(球)移动时,相机都会跟随它。
到目前为止,我设法通过在物理更新时不断移动相机来做到这一点,但它不是很有效并且有一些延迟。
func physicsWorld(world: SCNPhysicsWorld, didBeginContact contact: SCNPhysicsContact)
{
var cameraP = SCNVector3(x: ball.presentationNode().position.x, y: ball.presentationNode().position.y + 5, z: ball.presentationNode().position.z + 12)
camera.constraints = nil
camera.position = cameraP
camera.constraints = [SCNLookAtConstraint(target: ball)]
}
我阅读了一些关于 SCNTransformationConstraint
的信息,可以 "attach" 将摄像头连接到节点,但我没有找到可用的示例。
因为我想调整相机的位置,所以我无法将相机附加到节点上。
谢谢。
编辑:(给小胡子)
我尝试使用:
optional func renderer(_ renderer: SCNSceneRenderer, didSimulatePhysicsAtTime time: NSTimeInterval)
{
println("called")
}
但我收到一条错误消息:Extraneous '_' in parameter: 'rendered' has no keyword argument name
编辑 2(工作):
在 Moustach 的建议下,我们能够高效地完成这项工作。
相机位置现在更新于:
func renderer(aRenderer: SCNSceneRenderer, didSimulatePhysicsAtTime time: NSTimeInterval)
{
println("called")
}
此外,还创建了一个新的SCNNode
作为相机节点的根节点来保持其位置。
相机设置如下所示:
let lookAtBallConstraint = SCNLookAtConstraint(target: ball)
lookAtBallConstraint.gimbalLockEnabled = true
let tempCam = SCNCamera()
tempCam.zFar = 5000
camera = SCNNode()
camera.camera = tempCam
camera.position = SCNVector3(x: 0, y: 0, z: 0)
camera.constraints = [lookAtBallConstraint]
cameraPosition = SCNNode()
cameraPosition.position = SCNVector3(x: 0, y: 5, z: 12)
cameraPosition.addChildNode(camera)
现在相机移动功能如下所示:
func renderer(aRenderer: SCNSceneRenderer, didSimulatePhysicsAtTime time: NSTimeInterval)
{
var cameraP = SCNVector3(x: ball.presentationNode().position.x, y: ball.presentationNode().position.y + 5, z: ball.presentationNode().position.z + 12)
cameraPosition.position = cameraP
}
你似乎在每次球接触任何东西时都添加了一个新的约束,这可能每一帧都会发生很多次!
这是你应该做的:
- 将约束创建移动到只设置一次的地方,例如 init
- 将位置更新代码移动到 renderer delegate 以便它仅在一帧中被调用一次,就在物理计算完成之后。
你应该会看到一个巨大的性能更新!
编辑:试试这个
func renderer(aRenderer: SCNSceneRenderer, didSimulatePhysicsAtTime time: NSTimeInterval){
println("called")
}
我需要将 SCNCamera
附加到 SCNNode
以便每当节点(球)移动时,相机都会跟随它。
到目前为止,我设法通过在物理更新时不断移动相机来做到这一点,但它不是很有效并且有一些延迟。
func physicsWorld(world: SCNPhysicsWorld, didBeginContact contact: SCNPhysicsContact)
{
var cameraP = SCNVector3(x: ball.presentationNode().position.x, y: ball.presentationNode().position.y + 5, z: ball.presentationNode().position.z + 12)
camera.constraints = nil
camera.position = cameraP
camera.constraints = [SCNLookAtConstraint(target: ball)]
}
我阅读了一些关于 SCNTransformationConstraint
的信息,可以 "attach" 将摄像头连接到节点,但我没有找到可用的示例。
因为我想调整相机的位置,所以我无法将相机附加到节点上。
谢谢。
编辑:(给小胡子)
我尝试使用:
optional func renderer(_ renderer: SCNSceneRenderer, didSimulatePhysicsAtTime time: NSTimeInterval)
{
println("called")
}
但我收到一条错误消息:Extraneous '_' in parameter: 'rendered' has no keyword argument name
编辑 2(工作):
在 Moustach 的建议下,我们能够高效地完成这项工作。
相机位置现在更新于:
func renderer(aRenderer: SCNSceneRenderer, didSimulatePhysicsAtTime time: NSTimeInterval)
{
println("called")
}
此外,还创建了一个新的SCNNode
作为相机节点的根节点来保持其位置。
相机设置如下所示:
let lookAtBallConstraint = SCNLookAtConstraint(target: ball)
lookAtBallConstraint.gimbalLockEnabled = true
let tempCam = SCNCamera()
tempCam.zFar = 5000
camera = SCNNode()
camera.camera = tempCam
camera.position = SCNVector3(x: 0, y: 0, z: 0)
camera.constraints = [lookAtBallConstraint]
cameraPosition = SCNNode()
cameraPosition.position = SCNVector3(x: 0, y: 5, z: 12)
cameraPosition.addChildNode(camera)
现在相机移动功能如下所示:
func renderer(aRenderer: SCNSceneRenderer, didSimulatePhysicsAtTime time: NSTimeInterval)
{
var cameraP = SCNVector3(x: ball.presentationNode().position.x, y: ball.presentationNode().position.y + 5, z: ball.presentationNode().position.z + 12)
cameraPosition.position = cameraP
}
你似乎在每次球接触任何东西时都添加了一个新的约束,这可能每一帧都会发生很多次!
这是你应该做的:
- 将约束创建移动到只设置一次的地方,例如 init
- 将位置更新代码移动到 renderer delegate 以便它仅在一帧中被调用一次,就在物理计算完成之后。
你应该会看到一个巨大的性能更新!
编辑:试试这个
func renderer(aRenderer: SCNSceneRenderer, didSimulatePhysicsAtTime time: NSTimeInterval){
println("called")
}