旋转值之间的 Lerping 会导致游戏对象的位置发生变化

Lerping between values of rotations causes a position change of the gameObject

情况

在我的游戏中,我有一艘船,它会跟随我的手指在屏幕上的任何位置(或带有光线投射的鼠标,仅用于测试)。由于我想要实现的目标,我不想为运动或物理使用动画(动画对船的运动感觉不太好,而物理对于我正在做的事情来说太复杂了)。

这是我的移动和旋转控件:

 if (Input.GetMouseButton(0))
    {
        
        Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
        if (Physics.Raycast(ray, out hit, Mathf.Infinity, layerMask))
       {
            
            Vector3 target = hit.point;
            transform.position = Vector3.MoveTowards(transform.position,
             new Vector3(target.x, transform.position.y, target.z), speed);

            if(target.x - transform.position.x > 0)
            {
                right = true;
                isIdle = false;
            }
            else
            {
                right = false;
                isIdle = false;
            }
        }
    }
    else
    {
        isIdle = true;
        
        if (transform.rotation == originalRotation)
        {
            restoreRotation = false;
        }
        else
        {
            restoreRotation = true;
        }

        if (restoreRotation)
        {
            transform.rotation = Quaternion.Lerp(transform.rotation, originalRotation, Time.deltaTime * 5);
        }

这就是为什么我添加了 3 个协程 ,一个用于空闲旋转,一个用于向右旋转,一个用于向左旋转。比如这是右移的协程:

IEnumerator rightAnimation(float time)
{
    while (true)
    {

        if (right == true && isIdle == false)
        {
            float elapsedTime = 0;

            if (transform.rotation != Quaternion.Euler(-2, 13, -8))
            {

                while (elapsedTime < time)
                {
                    transform.rotation = Quaternion.Lerp(transform.rotation, Quaternion.Euler(-2, 13, -8), (elapsedTime / time));
                    elapsedTime += Time.deltaTime;

                    yield return null;
                }
            }

            elapsedTime = 0;

            while (elapsedTime < time)
            {
                transform.rotation = Quaternion.Lerp(Quaternion.Euler(-2, 13, -8), Quaternion.Euler(-7, 13, -8), (elapsedTime / time));
                elapsedTime += Time.deltaTime;

                yield return null;
            }

            elapsedTime = 0;

            while (elapsedTime < time)
            {
                transform.rotation = Quaternion.Lerp(Quaternion.Euler(-7, 13, -8), Quaternion.Euler(-2, 13, -8), (elapsedTime / time));
                elapsedTime += Time.deltaTime;

                yield return null;
            }
        }

        yield return new WaitForSeconds(0.1f);
    }

如果 right == true 那么我的协程会检查旋转并 lerp 到新的旋转。我检查了 inspector 上的值,看起来不错,就像这样:

没有位置变化,这是完美的,因为位置由 MoveTowards 非常简单地控制。

当我在游戏中尝试我的代码时,协同程序工作正常并且它们以正确的方式循环但是发生了这种情况:

我的相机无法跟随船的中心,没有动画也能很好地跟随,船比我的手指向右移动了一点,有时它甚至破坏了协同程序,因为如果我继续拖动手指向右,看起来我还在船上,但 Unity 认为我正在向左移动,所以它迅速改变动画并向左移动 2-3 个单位,就像传送一样。

我一开始以为是 pivot 的问题,但是船实际上只是一个空的 gameObject,在船的模型里面,而且都是居中的:

我不知道,我不会以任何方式改变旋转之间的 Lerp 的位置,所以我对此一无所知

你不是通过代码让相机跟船吗?

如果我是对的,只需添加一个脚本让相机跟随船,一切都应该正常...我猜

实际上我通过移除电影机解决了这个问题,基本上,它造成了这些问题:

  1. 它跟随船的旋转,导致奇怪的视角
  2. 旋转的变化改变了光线投射的方向,导致船快速变化并出现位置故障

有了新相机和我编写的代码,它现在工作得很好!