Unity3D开关摄像头模式 - 旋转Freecam跳跃



我正在创建一个自定义相机来查看3D对象。相机通常是飞凸轮,但在物体的阻力上,我希望相机绕对象绕。我已经实现了这一点,但是在模式之间交换时,相机在位置之间跳跃。我将如何平滑,以便在轨道之后保持相同的位置,并且用户可以从该位置继续以飞行凸轮模式继续进行。这是我的代码:

    if (!rotateToggle)
    {
        if (Input.GetMouseButton(0)){
            rotationX += Input.GetAxis("Mouse X") * cameraSensitivity * Time.deltaTime;
            rotationY += Input.GetAxis("Mouse Y") * cameraSensitivity * Time.deltaTime;
        }
        rotationY = Mathf.Clamp(rotationY, -90, 90);
        transform.localRotation = Quaternion.AngleAxis(rotationX, Vector3.up);
        transform.localRotation *= Quaternion.AngleAxis(rotationY, Vector3.left);
        if (Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift))
        {
            cameraSpeed = 150f;
        }
        else
        {
            cameraSpeed = 50f;
        }

        transform.position += transform.forward * cameraSpeed * Input.GetAxis("Vertical") * Time.deltaTime;
        transform.position += transform.right * cameraSpeed * Input.GetAxis("Horizontal") * Time.deltaTime;
    }else{
        rotationX = Input.GetAxis("Mouse X") * RotateAmount;
        rotationY = Input.GetAxis("Mouse Y") * RotateAmount;
        Vector3 angles = transform.eulerAngles;
        angles.z = 0;
        transform.eulerAngles = angles;
        transform.RotateAround(rotationTarget.position, Vector3.up, rotationX);
        transform.RotateAround(rotationTarget.position, Vector3.left, -rotationY);
        transform.LookAt(rotationTarget);
    }
当用户拖动对象并且rotationTarget是轨道目标的变换时,

rotateToggle是正确的。

谢谢!

编辑:在进行进一步研究时,纯粹是旋转角,而不是前面所述的实际位置!再次感谢

edit2:为了进一步澄清,我希望能够保持旋转值:

transform.localRotation = Quaternion.AngleAxis(rotationX, Vector3.up);
transform.localRotation *= Quaternion.AngleAxis(rotationY, Vector3.left);

和:

            transform.eulerAngles = angles;
            transform.RotateAround(rotationTarget.position, Vector3.up, rotationX);
            transform.RotateAround(rotationTarget.position, Vector3.left, -rotationY);
            transform.LookAt(rotationTarget);

交换相机模式

可以使用vector3.lerp和coroutines实现这一目标。

每当您的rotateToggle -flag更改其值时 - 可能是按下按钮或鼠标单击时 - 启动coroutine(在此处进行有关coroutines的更多信息(,并使用vector3.lerp.lerp(或quaternion.lerp for Rotations.也可以工作 - 在此处链接到vector3.lerp文档(。因此,您将在两种状态之间进行平稳的过渡,并且可能会调整过渡的时间。

虽然相机位置和旋转是通过这种方式进行的,a(a(锁定用户不转换和b(不要在问题中执行您的代码,因为它们会干扰coroutine(上面的代码将设置旋转设置旋转并立即定位到其"最终状态",而Coroutine将其设置为变量"过渡状态"(。

不幸的是,我现在没有示例代码。

我能够通过将一些LERP和速度连续增加来解决此问题:

        if (!rotateToggle)
        {
            if (Input.GetMouseButton(0))
            {
                rotationX += Input.GetAxis("Mouse X") * cameraSensitivity * Time.deltaTime;
                rotationY += Input.GetAxis("Mouse Y") * cameraSensitivity * Time.deltaTime;
            }
            rotationY = Mathf.Clamp(rotationY, -90, 90);
            transform.localRotation = transform.localRotation * Quaternion.AngleAxis(rotationX, Vector3.up);
            transform.localRotation = transform.localRotation * Quaternion.AngleAxis(rotationY, Vector3.left);
            transform.localRotation = Quaternion.Euler(transform.localRotation.eulerAngles.x, transform.localRotation.eulerAngles.y, 0);
            if (Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift))
            {
                cameraSpeed = 150f;
            }
            else
            {
                cameraSpeed = 50f;
            }

            transform.position += transform.forward * cameraSpeed * Input.GetAxis("Vertical") * Time.deltaTime;
            transform.position += transform.right * cameraSpeed * Input.GetAxis("Horizontal") * Time.deltaTime;
            rotationX = Mathf.Lerp(rotationX, 0f, 0.1f);
            rotationY = Mathf.Lerp(rotationY, 0f, 0.1f);
        }
        else
        {
            rotationX = Input.GetAxis("Mouse X") * RotateAmount;
            rotationY = Input.GetAxis("Mouse Y") * RotateAmount;
            Vector3 angles = transform.eulerAngles;
            angles.z = 0;
            transform.eulerAngles = angles;
            transform.RotateAround(rotationTarget.position, Vector3.up, rotationX);
            rotationY = Mathf.Clamp(rotationY, -30, 30);
            transform.RotateAround(rotationTarget.position, Vector3.left, -rotationY);
            transform.localRotation = Quaternion.Euler(transform.localRotation.eulerAngles.x, transform.localRotation.eulerAngles.y, 0);
        }

我还添加了一个lookat coroutine以平滑过渡:

IEnumerator LerpToTarget()
{
    float time = 0;
    while (time < 0.1f)
    {
        Vector3 pos = rotationTarget.transform.position-transform.position;
        var newRot = Quaternion.LookRotation(pos);
        transform.rotation = Quaternion.Lerp(transform.rotation, newRot, 0.1f);
        time += Time.deltaTime;
        yield return null;
    }
    StartCoroutine(LookAtTarget());
}
IEnumerator LookAtTarget()
{
    while (rotateToggle)
    {
        transform.LookAt(rotationTarget);
        yield return null;
    }
}

这肯定可以改善,因为还有一些上下轨道的问题。

最新更新