Currently working on a game in scenekit with swift, and i'm trying to implement camera constraints to take full advantage of everything scenekit has to offer. I am very close to getting what I want, but i am missing one piece and cannot seem to figure it out. Videos of the issue below.
This video shows my camera following my ship with code I wrote. The orientation and angle are good, and it follows with a nice inertia. I achieve this with the follow code:
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 shows the camera following my ship with constraints. It seems to just be rotating on the x,z axis. So i'd really like for it to move back and forth across the x,z axis like the code I wrote... or something similar. These constraints are taken from the WWDC 2017 scenekit fox demo, and i've implimented them like so:
// 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]
If anybody has any idea how i can achieve this i'd love to hear it! There isn't any documentation about these new constraints so i'm kind of just guessing when i put them on.