繁体   English   中英

Unity3D切换相机模式-跳至FreeCam跳跃

[英]Unity3D Switching Camera Modes - Orbit to FreeCam Jumping

我正在创建自定义相机以查看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是轨道目标的变换时,rotationToggle为true。

谢谢!

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

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标志更改其值时(可能是在按下按钮或单击鼠标时)启动协程( 此处有关于程的更多信息),并使用Vector3.Lerp(或Quaternion.Lerp for Rotations)插值位置和旋转- 在此处链接到Vector3.Lerp文档)。 因此,您将在两种状态之间获得平稳的过渡,并可以调整过渡需要多长时间。

虽然以此方式限制了摄像机的位置和旋转,但是您应该a)锁定用户的不操作,并且b)不要执行问题中发布的代码,因为它们会干扰协同程序(上面的代码会将旋转和位置设置为协程会将其设置为变量“过渡状态”)。

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

我可以通过砍一些子并使速度不断提高来解决此问题:

        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);
        }

我还添加了外观协程以平滑过渡:

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;
    }
}

由于上下轨道仍然存在一些问题,因此绝对可以改善。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM