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的信息,可以"附加"相机到节点,但我发现没有工作的例子。

我不能仅仅将摄像机附加到节点上,因为我想调整摄像机的位置。

谢谢。

编辑:(对小胡子)

我尝试使用:

optional func renderer(_ renderer: SCNSceneRenderer, didSimulatePhysicsAtTime time: NSTimeInterval)
{
    println("called")
}

,但我得到一个错误说:Extraneous '_' in parameter: 'rendered' has no keyword argument name

Edit 2 (working):

在Moustach的建议下,我们能够有效地完成这项工作。

摄像机位置现在更新为:

func renderer(aRenderer: SCNSceneRenderer, didSimulatePhysicsAtTime time: NSTimeInterval)
{
    println("called")
}

此外,创建了一个新的SCNNode作为相机节点的rootNode来保持其位置。

设置相机现在看起来像这样:

        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
  • 将位置更新代码移动到渲染代理中,这样它只在物理计算完成后一帧被调用一次。

你应该看到一个巨大的性能更新!

编辑:try this

func renderer(aRenderer: SCNSceneRenderer, didSimulatePhysicsAtTime time: NSTimeInterval){
    println("called")
}

最新更新