Swift Scenekit Camera: в направлении персонажа - PullRequest
0 голосов
/ 05 мая 2018

Я пытаюсь создать свою собственную игру, используя 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]
}
...