我正在尝试使用Swift创建自己的游戏,我想知道如何在SceneKit中使用相机将其固定在角色头部的背面,并随着相机移动和旋转。
我的第一个想法是让角色的方向等于相机的方向,但这不起作用。
我的第二个想法是使用一些相机限制,但它们似乎都不起作用。我使用了lookAtConstraint,replicatorConstraint和distanceConstraint的组合。我当时认为使用IKConstraint可能会有效,但是当我使用它时总会给我一个错误。
如果有人有任何建议会得到很好的理解,我对于使用的内容有点用尽了。谢谢!!
以下是设置相机的功能:
func setupFollowCamera(_ cameraNode: SCNNode) {
// look at "lookAtTarget"
let lookAtConstraint = SCNLookAtConstraint(target: self.lookAtTarget)
lookAtConstraint.influenceFactor = 0.07
lookAtConstraint.isGimbalLockEnabled = true
// distance constraints
let follow = SCNDistanceConstraint(target: self.lookAtTarget)
let distance = CGFloat(simd_length(cameraNode.simdPosition))
follow.minimumDistance = distance
follow.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
guard let strongSelf = weakSelf else { return position }
var position = float3(position)
position.y = strongSelf.character!.baseAltitude + Float(0.75)
return SCNVector3( position )
})
// replicator constraint
let repli = SCNReplicatorConstraint(target: self.lookAtTarget)
repli.positionOffset = SCNVector3(0, 0, 1)
repli.replicatesOrientation = true
//let ik = SCNIKConstraint(chainRootNode: (self.character?.node)!)
// use a custom constraint to let the user orbit the camera around the character
let transformNode = SCNNode()
let orientationUpdateConstraint = SCNTransformConstraint(inWorldSpace: true) { (_ node: SCNNode, _ transform: SCNMatrix4) -> SCNMatrix4 in
guard let strongSelf = weakSelf else { return transform }
if strongSelf.activeCamera != node {
return transform
}
let targetPosition = strongSelf.lookAtTarget.presentation.simdWorldPosition
let cameraDirection = strongSelf.cameraDirection
//let cameraDirection = strongSelf.characterDirection
if cameraDirection.allZero() {
return transform
}
let characterWorldUp = strongSelf.character?.node?.presentation.simdWorldUp
transformNode.transform = transform
let q = simd_mul(
simd_quaternion(GameController.CameraOrientationSensitivity * cameraDirection.x, characterWorldUp!),
simd_quaternion(GameController.CameraOrientationSensitivity * cameraDirection.y, transformNode.simdWorldRight)
)
transformNode.simdRotate(by: q, aroundTarget: targetPosition)
return transformNode.transform
}
//cameraNode.constraints = [keepAltitude, orientationUpdateConstraint, lookAtConstraint, follow]
cameraNode.constraints = [lookAtConstraint, repli]
}