【问题标题】:3rd Person Camera in SceneKitSceneKit 中的第三人称相机
【发布时间】:2015-10-07 05:10:19
【问题描述】:

我需要将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

编辑 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
}

【问题讨论】:

    标签: ios swift camera scenekit scnnode


    【解决方案1】:

    似乎每次球碰到任何东西时你都在添加一个新的约束,这可能每帧都会发生很多!

    这是你应该做的:

    • 将约束创建移动到仅设置一次的位置,例如 init
    • 将位置更新代码移动到renderer delegate,这样它就只在计算物理之后每帧调用一次。

    您应该会看到巨大的性能更新!

    编辑:试试这个

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

    【讨论】:

    • edit:请检查问题编辑。无法在注释中正确格式化代码
    • 我更新了我的答案。我不小心链接到了 beta 文档和命名不同的变量。
    • 感谢新的变量名称,我没有收到错误消息,但该函数仍然没有被调用,我在控制台中也没有看到“调用”。不知道为什么它被忽略了。
    • 你把这段代码放在哪里了?它必须符合SCNSceneRendererDelegate。你可以在这里看到一个例子:stackoverflow.com/a/27849394/2053038
    猜你喜欢
    • 2012-11-03
    • 1970-01-01
    • 1970-01-01
    • 2013-04-01
    • 2021-06-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-07-23
    相关资源
    最近更新 更多