随着时间旋转GameObject [英] Rotate GameObject over time

查看:175
本文介绍了随着时间旋转GameObject的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在这里是新来的,我尝试开始使用Unity Engine.

I a new here and i try to start working with Unity Engine.

有人可以向我解释一下Quaternion.Slerp的工作原理吗?因为我想以90、180和270度的角度旋转某个对象.我的代码如下所示.不幸的是,当我增加180度时,对象会做出疯狂的事情,而不是将此游戏对象的旋转度设为(0,180,180).我想得到(180,0,0)

Could somebody explain me, how works Quaternion.Slerp? Because I want to rotate some object in different angles 90, 180 and 270. My code you can see below. Unfortunately when I add 180 degrees, object make crazy things and than put rotation to (0, 180, 180) for this game object. I would like to get (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);

    }

推荐答案

目前,包括官方网站上的Unity示例在内的大多数示例都以错误的方式使用了Lerp.他们甚至不费心地在API文档中描述它的工作方式.他们只是在Update()函数中添加淀粉,然后将其命名为一天.

Most examples out there including Unity examples from their official website are using Lerp in the wrong way. They didn't even bother to describe how it works in the API documentation. They just starch it in the Update() function and call it a day.

Mathf.LerpVector3.LerpQuaternion.Slerp的工作方式是通过传递一个 t 值(最后一个参数)从一个位置/旋转更改为另一位置/旋转./strong>值也称为时间.

Mathf.Lerp, Vector3.Lerp, and Quaternion.Slerp work by changing from one position/rotation to another with the t value(last parameter) being passed in.That t value is also know as time.

t 值的最小值为 0f ,最大值为 1f .

The min of the t value is 0f and the max is 1f.

我将用Mathf.Lerp对此进行解释,以使其更易于理解. Lerp功能对于Mathf.LerpVectorQuaternion都是相同的.

I will explain this with Mathf.Lerp to make it easier to understand. The Lerp functions are all the-same for both Mathf.Lerp, Vector and Quaternion.

请记住,Lerp接受两个值并在它们之间返回值.如果我们的值为 1 10 并且对它们进行Lerp:

Remember that Lerp takes two values and returns values between them. If we have a value of 1 and 10 and we do Lerp on them:

 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

如您所见,t(0)返回传入的数字的 min t(1)返回传入的 max 值,而t(0.5)将返回介于 min max 值之间的点.传递< 0> 1的任何 t 值时,这样做是错误的. Update()函数中的代码就是这样做的. Time.time将每秒增加一次,而在一秒内将变为> 1,因此您会遇到问题.

As you can see, the t(0) returns the min of the number passed in, t(1) returns the max value passed in and t(0.5) will return mid point between the min and the max value. You are doing it wrong when you pass any t value that is < 0 or > 1. That code in you Update() function is doing just that. Time.time will increase every second and will be > 1 in a second, so you have problems with that.

建议在其他功能/协程中使用Lerp而不是更新"功能.

It recommended to use Lerp in another function/Coroutine instead of the Updated function.

注意:

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

Using Lerp has a bad side of it when it comes to rotation. Lerp does not know how to rotate Object with the shortest path. So bear that in mind. For example, you have an Object with 0,0,90 position. Lets say you want to move the rotation from that to 0,0,120 Lerp can sometimes rotate left instead of right to reach that new position which means it take longer to reach that distance.

比方说,无论当前旋转角度是什么,我们都要旋转(0,0,90).下面的代码将在3秒内将旋转角度更改为0,0,90.

Let's say we want to make the rotation (0,0,90) from whatever the current rotation is. The code below will change the rotation to 0,0,90 in 3 seconds.

一段时间内旋转:

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;
}

随时间的增量角旋转:

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

And to just rotate the Object to 90 in z axis, the code below is a great example of that. Please understand there is a difference between moving Object to new rotational point and just rotating it.

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;
}

我所有的示例均基于设备的帧频.您可以通过将Time.deltaTime替换为Time.delta来使用实时功能,但需要更多的计算.

All my examples are based on frame-rate of the device. You can use real-time by replacing Time.deltaTime with Time.delta but more calculation is required.

这篇关于随着时间旋转GameObject的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆