随着时间的推移旋转游戏对象 [英] Rotate GameObject over time

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

问题描述

我是新来的,我尝试开始使用 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 值(最后一个参数)被传入.t 值也称为时间.

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 接受两个值并返回它们之间的值.如果我们有 110 的值,并且我们对它们进行 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) 返回传入数字的mint(1) 返回<传入的strong>ma​​x 值和t(0.5) 将返回minma​​x<之间的mid 点/strong> 值.当您传递 < 的任何 t 值时,您就做错了.0>1.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 而不是 Updated 函数.

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

注意:

使用 Lerp 在轮换方面有不好的一面.Lerp 不知道如何以最短路径旋转对象.所以请记住这一点.例如,您有一个 0,0,90 位置的对象.假设您想将旋转从那个移动到 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.

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

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