随着时间的推移旋转GameObject

Eve*_*986 2 c# quaternions unity-game-engine

我是新手,我尝试开始使用Unity Engine.

有人可以解释一下,Quaternion.Slerp怎么样?因为我想以不同的角度90,180和270旋转一些物体.我可以在下面看到我的代码.不幸的是,当我添加180度时,对象会做出疯狂的事情,而不是将旋转放到(0,180,180)这个游戏对象.我想得到(180,0,0)

    public float speed = 0.1F;
    private float rotation_x;
    void Update()
    {
        if (Input.GetButtonDown("Fire1"))
        {
            rotation_x = transform.rotation.eulerAngles.x;
            rotation_x += 180;
        }
        transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.Euler(rotation_x, transform.eulerAngles.y, transform.eulerAngles.z), Time.time * speed);

    }
Run Code Online (Sandbox Code Playgroud)

Pro*_*mer 12

大多数示例包括他们官方网站上的Unity示例都以错误的方式使用Lerp.他们甚至懒得描述它在API文档中的工作原理.他们只是将它淀粉在Update()功能中并称之为一天.

Mathf.Lerp,Vector3.Lerp以及Quaternion.Slerp通过从一个位置/旋转变换到另一种与工作值(最后一个参数)被传递in.That 值也被知道为时间.

所述的最小值是0F和max为1F.

我将解释这一点,Mathf.Lerp以便更容易理解.两者的Lerp功能都是相同的Mathf.Lerp,VectorQuaternion.

请记住,它Lerp采用两个值并在它们之间返回值.如果我们的值为110,我们会对它们执行Lerp:

 float x = Mathf.Lerp(1f, 10f, 0f); will return 1.
 float x = Mathf.Lerp(1f, 10f, 0.5f); will return 5.5
 float x = Mathf.Lerp(1f, 10f, 1f);  will return 10
Run Code Online (Sandbox Code Playgroud)

如您所见,t(0)返回传入的数字的最小值,t(1)返回传入的最大值,并t(0.5)返回最小值最大值之间的中间点.你做错了,当你通过任何牛逼值,或.你功能中的代码就是这样做的.每秒都会增加,并且会在一秒钟内增加,所以你有问题.< 0> 1Update()Time.time> 1

它建议Lerp在另一个函数/ Coroutine中使用,而不是使用Updated函数.

注意:

Lerp在旋转方面,使用它有不好的一面.Lerp不知道如何用最短路径旋转对象.所以记住这一点.例如,您有一个具有0,0,90位置的对象.假设您想要将旋转从那里移动到0,0,120 Lerp有时可以向左旋转而不是向右旋转以到达新位置,这意味着需要更长的时间才能到达该距离.

假设我们想要(0,0,90)从当前旋转的任何位置进行旋转.下面的代码会将旋转更改为0,0,903秒.

轮流时间:

void Start()
{
    Quaternion rotation2 = Quaternion.Euler(new Vector3(0, 0, 90));
    StartCoroutine(rotateObject(objectToRotate, rotation2, 3f));
}

bool rotating = false;
public GameObject objectToRotate;
IEnumerator rotateObject(GameObject gameObjectToMove, Quaternion newRot, float duration)
{
    if (rotating)
    {
        yield break;
    }
    rotating = true;

    Quaternion currentRot = gameObjectToMove.transform.rotation;

    float counter = 0;
    while (counter < duration)
    {
        counter += Time.deltaTime;
        gameObjectToMove.transform.rotation = Quaternion.Lerp(currentRot, newRot, counter / duration);
        yield return null;
    }
    rotating = false;
}
Run Code Online (Sandbox Code Playgroud)

随时间增加角度旋转:

要在z轴上将对象旋转到90,下面的代码就是一个很好的例子.请理解将物体移动到新的旋转点并旋转它之间有区别.

void Start()
{
    StartCoroutine(rotateObject(objectToRotate, new Vector3(0, 0, 90), 3f));
}

bool rotating = false;
public GameObject objectToRotate;

IEnumerator rotateObject(GameObject gameObjectToMove, Vector3 eulerAngles, float duration)
{
    if (rotating)
    {
        yield break;
    }
    rotating = true;

    Vector3 newRot = gameObjectToMove.transform.eulerAngles + eulerAngles;

    Vector3 currentRot = gameObjectToMove.transform.eulerAngles;

    float counter = 0;
    while (counter < duration)
    {
        counter += Time.deltaTime;
        gameObjectToMove.transform.eulerAngles = Vector3.Lerp(currentRot, newRot, counter / duration);
        yield return null;
    }
    rotating = false;
}
Run Code Online (Sandbox Code Playgroud)

我的所有示例都基于设备的帧速率.您可以通过替换实时使用Time.deltaTime,Time.delta但需要更多计算.