unity3d 围绕角色旋转时摄像机 Flink

6uxekuva  于 2023-02-16  发布在  Flink
关注(0)|答案(1)|浏览(229)

我的相机在绕着一个特定的点旋转后 Flink 。有人能告诉我是什么问题吗?我也分享了图片,图片在场景帧和剪切工具帧enter image description here之间 Flink 了很多

using UnityEngine;

public class CameraFollowMain : MonoBehaviour
{
    [SerializeField] private Transform target;
    [SerializeField] private float camMotionSpeed = 2f;
    [SerializeField] private float camDistance = 1.5f;
    Vector3 offset;

    // Start is called before the first frame update
    void Start()
    {
        //gets the distance between 2 vectors in vector format. 
        offset = (transform.position + target.position).normalized * camDistance; 
    }

    // Update is called once per frame
    void FixedUpdate()
    {
        transform.position = target.position + offset;
        offset = Quaternion.AngleAxis(Input.GetAxis("Mouse X") * camMotionSpeed, Vector3.up) * offset;
        offset = Quaternion.AngleAxis(Input.GetAxis("Mouse Y") * camMotionSpeed, Vector3.right) * offset;
        transform.LookAt(target.transform.position);
    }
}

我已经尝试了这个代码,我期待着相机旋转周围的字符一样,在GTA5

7vux5j2d

7vux5j2d1#

相机“ Flink ”的原因是“Gimbal lock“效应。

万向节锁定是指三维三万向节机构中的一个自由度损失,当三个万向节中的两个的轴被驱动成平行配置时发生,“锁定”系统在退化的二维空间中旋转。

在这段代码中,我不处理障碍物,只跟踪和观察目标:

using UnityEngine;

public class CameraFollow : MonoBehaviour
{
    [SerializeField] private Transform target;
    
    [SerializeField] private float rotationSpeed = 5f;
    [SerializeField] private float viewDistance = 1.5f;
    
    [Range(-90f, 90f)]
    [SerializeField] private float minVerticalAngle = -90f;
    [Range(-90f, 90f)]
    [SerializeField] private float maxVerticalAngle = 90f;
    
    [SerializeField] private float rotationSensitive = 10000f;
    [SerializeField] private float followingSensitive = 10000f;
    [SerializeField] private float distanceMovementSensitive = 10f;
    
    private Vector3 planarDirection;
    private float targetVerticalAngle;
    private Vector3 currentPosition;
    private float currentDistance;

    void Start()
    {
        planarDirection = Vector3.forward;
        targetVerticalAngle = 0f;
        currentPosition = target.position;
    }

    void Update()
    {
        var deltaTime = Time.deltaTime;
        var rotationInput = new Vector3(Input.GetAxis("Mouse X"), Input.GetAxis("Mouse Y"), 0f);
        var targetTransformUp = target.transform.rotation * Vector3.up;
        
        var rotationFromInput = Quaternion.Euler(targetTransformUp * (rotationInput.x * rotationSpeed));
        planarDirection = rotationFromInput * planarDirection;
        planarDirection = Vector3.Cross(targetTransformUp, Vector3.Cross(planarDirection, targetTransformUp));
        var planarRotation = Quaternion.LookRotation(planarDirection, targetTransformUp);

        targetVerticalAngle -= (rotationInput.y * rotationSpeed);
        targetVerticalAngle = Mathf.Clamp(targetVerticalAngle, minVerticalAngle, maxVerticalAngle);
        
        var verticalRotation = Quaternion.Euler(targetVerticalAngle, 0, 0);
        var targetRotation = Quaternion.Slerp(
            transform.rotation,
            planarRotation * verticalRotation,
            1f - Mathf.Exp(-rotationSensitive * deltaTime));

        transform.rotation = targetRotation;
        
        currentPosition = Vector3.Lerp(currentPosition, target.position, 1f - Mathf.Exp(-followingSensitive * deltaTime));
        currentDistance = Mathf.Lerp(currentDistance, viewDistance, 1 - Mathf.Exp(-distanceMovementSensitive * deltaTime));
        transform.position = currentPosition - ((targetRotation * Vector3.forward) * currentDistance);
    }
}

相关问题