我正在创建一个自定义相机来查看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);
}
当用户拖动对象时,rotateToggle为true,而rotationTarget是轨道目标的变换。
谢谢!
编辑:进一步调查时,它纯粹是旋转角度,而不是前面所述的实际位置!再次感谢
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);
交换相机模式时
答案 0 :(得分:1)
这可以使用Vector3.Lerp和Coroutines来实现。
每当您的rotateToggle-flag更改其值时 - 可能是在按下按钮或单击鼠标时 - 启动协程(有关coroutines here的更多信息)并使用Vector3.Lerp(或Quaternion)插入位置和旋转。 Lerp for Rotations也可以工作 - 链接到Vector3.Lerp文档here)。因此,您将在两个状态之间实现平滑过渡,并且还可以调整过渡所需的时间。
虽然以这种方式拍摄相机的位置和旋转,但你应该a)锁定用户的unteractions和b)不执行你的问题中发布的代码,因为它们会干扰协程(上面的代码会设置旋转并立即定位到“结束状态”,而协程将其设置为变量“过渡状态”。)
不幸的是,我现在手边没有示例代码。
答案 1 :(得分:0)
我能够通过混淆一些lerps并允许速度不断增加来解决这个问题:
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协程以平滑过渡:
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;
}
}
这绝对可以改善,因为上下轨道仍然存在一些问题。