Unity:使用触摸抓取移动旋转时相机为jumpy/jerky

Unity: Camera is jumpy/jerky when using touch grab to move rotation

使用 Unity,我尝试使用第一人称相机通过触摸移动我的炮塔旋转,我从屏幕的一侧抓取到中心,从我想去的方向在 google 地图中喜欢, touch grab 会把我的相机顺畅地移动到那里。

问题是相机非常不稳定,位置不平滑。

在全球

private float smoothTouchFactor = 5;

这是我在 Update()

中使用的代码
Quaternion rotation;

if (Input.touchCount > 0)
{
    if (Input.GetTouch(0).phase == TouchPhase.Moved)
    {
        Touch touch = Input.GetTouch(0);
        x += touch.deltaPosition.x * xSpeed * 0.02f;
        y -= touch.deltaPosition.y * ySpeed * 0.02f;

        rotation = Quaternion.Euler(y, x, 0f);
        turretHeadToMove.rotation = Quaternion.Slerp(turretHeadToMove.rotation, rotation, Time.deltaTime * smoothTouchFactor);
    }
}

rotation = Quaternion.Euler(y, x, 0f);
turretHeadToMove.rotation = Quaternion.Slerp(turretHeadToMove.rotation, rotation, Time.deltaTime * smoothTouchFactor);

如果我不在 if(touchCount) 之后添加最后两行,那么当我将手指从屏幕上移开后,相机会回到初始位置。


这里是鼠标轴鼠标 X/Y 代码,它可以正常工作并平稳地移动炮塔,没有抖动。

private float xSpeed = 40.0f;
private float ySpeed = 40.0f;

in Update()
x += Input.GetAxis("Mouse X") * xSpeed * 0.02f;
y -= Input.GetAxis("Mouse Y") * ySpeed * 0.02f;

Quaternion rotation = Quaternion.Euler(y, x, 0f);
turretHeadToMove.rotation = rotation;

根据您对最后需要那些 "two lines" 的描述,听起来您在其他地方有不断尝试重置其轮换的代码。所以,我们添加一个变量来保持 rotation 与上次完成触摸控制时设置的 Quaternion 一致,并且在处理触摸控制之前一定要将它分配给 turretHeadToMove.rotation

然后,您可以使用 Euler 创建一个 Quaternion 来表示您想要将此框架旋转多少度。然后将当前旋转乘以该数量以获得新的旋转

总的来说,这可能是这样的:

作为一个字段:

private Quaternion savedRotation = Quaternion.identity;

Update中:

// Add it before the block so that modifications to `localRotation` are consistent with memory
turretHeadToMove.rotation = savedRotation;

if (Input.touchCount > 0)
{
    if (Input.GetTouch(0).phase == TouchPhase.Moved)
    {
        Touch touch = Input.GetTouch(0);
        Quaternion previousRotation = turretHeadToMove.rotation;

        Quaternion rotationThisFrame = Quaternion.Euler(
                 touch.deltaPosition.y * ySpeed, 
                 touch.deltaPosition.x * xSpeed, 0f);

        turretHeadToMove.rotation = previousRotation * rotationThisFrame;

        savedRotation = turretHeadToMove.rotation;
    }
}