【问题标题】:SceneKit camera constraint behaviour issuesSceneKit 相机约束行为问题
【发布时间】:2019-01-02 14:32:11
【问题描述】:

目前正在使用 swift 在 scenekit 中开发游戏,我正在尝试实现相机约束以充分利用 Scenekit 提供的所有功能。我非常接近得到我想要的东西,但我错过了一件,似乎无法弄清楚。以下问题的视频。

This video 用我编写的代码显示我的相机跟随我的船。方向和角度都很好,并且具有很好的惯性。我通过以下代码实现了这一点:

func renderer(_ renderer: SCNSceneRenderer, updateAtTime time: TimeInterval) {
    updateCameraPosition()
}

func updateCameraPosition () {
    let currentPosition = player.node.presentation.position
    let newVector = getNewCameraVector(currentPosition: currentPosition, t: 0.03 )

    cameraNode.runAction( SCNAction.move(to: newVector, duration: 0.2) )

    prevCameraPosition = currentPosition
}

func getNewCameraVector (currentPosition:SCNVector3, t: Float) -> SCNVector3 {
    let x = (1 - t) * prevCameraPosition.x + t * currentPosition.x
    let y = cameraZoom
    let z = ((1 - t) * prevCameraPosition.z + t * currentPosition.z) + cameraZPos!

    return SCNVector3(x,y,z)
}

This video 显示相机跟随我的船有约束。它似乎只是在 x、z 轴上旋转。所以我真的很想让它像我写的代码一样在 x、z 轴上来回移动......或类似的东西。这些约束取自 WWDC 2017 scenekit fox 演示,我已经像这样实现了它们:

    // look at "lookAtTarget"
    let lookAtConstraint = SCNLookAtConstraint(target: player.node)
    lookAtConstraint.influenceFactor = 0.07
    lookAtConstraint.isGimbalLockEnabled = true

    // distance constraints
    let distanceConstraint = SCNDistanceConstraint(target: player.node)
    let distance = CGFloat(simd_length(cameraNode.simdPosition))
    distanceConstraint.minimumDistance = distance
    distanceConstraint.maximumDistance = distance

    // configure a constraint to maintain a constant altitude relative to the character
    //let desiredAltitude = abs(cameraNode.simdWorldPosition.y)
    //weak var weakSelf = self

    let keepAltitude = SCNTransformConstraint.positionConstraint(inWorldSpace: true, with: {(_ node: SCNNode, _ position: SCNVector3) -> SCNVector3 in
        return SCNVector3(0, self.cameraZoom, self.cameraZoom)
    })

    let accelerationConstraint = SCNAccelerationConstraint()
    accelerationConstraint.maximumLinearVelocity = 1500.0
    accelerationConstraint.maximumLinearAcceleration = 50.0
    accelerationConstraint.damping = 0.05

    cameraNode.constraints = [distanceConstraint, keepAltitude, accelerationConstraint, lookAtConstraint]

如果有人知道我如何实现这一点,我很想听听!没有任何关于这些新约束的文档,所以我只是在猜测我什么时候戴上它们。

【问题讨论】:

    标签: ios swift scenekit


    【解决方案1】:

    回答我自己的问题,希望对其他人有所帮助。我终于能够复制具有以下约束的相机代码:

    func setupCamera () {
        cameraNode.camera = SCNCamera()
        cameraZPos = cameraZoom / 2 // cameraZoom == 100
    
        if let cam = cameraNode.camera {
            cam.zFar = cameraZFar
        }
    
        let replicatorConstraint = SCNReplicatorConstraint(target: player.node)
        replicatorConstraint.positionOffset = SCNVector3(0,cameraZoom,cameraZPos!)
        replicatorConstraint.replicatesOrientation = false
    
        let lookAtConstraint = SCNLookAtConstraint(target: player.node)
        lookAtConstraint.influenceFactor = 0.07
        lookAtConstraint.isGimbalLockEnabled = true
    
        let accelerationConstraint = SCNAccelerationConstraint()
        accelerationConstraint.maximumLinearAcceleration = 300.0
    
        cameraNode.constraints = [replicatorConstraint, lookAtConstraint, accelerationConstraint]
    }
    

    如果您有任何问题,请在此答案上发表评论,我很乐意分享我学到的知识!

    【讨论】:

    • 非常有用的答案 - 很难找到有关 SNCConstraint 的工作示例代码。
    猜你喜欢
    • 2023-03-29
    • 1970-01-01
    • 2011-07-06
    • 1970-01-01
    • 2021-11-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多