我正在创建一个自定义相机来查看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;
}
}
这肯定可以改善,因为还有一些上下轨道的问题。