随着时间的推移旋转游戏对象

Posted

技术标签:

【中文标题】随着时间的推移旋转游戏对象【英文标题】:Rotate GameObject over time 【发布时间】:2022-01-14 08:30:08 【问题描述】:

我是新来的,我尝试开始使用 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);

    

【问题讨论】:

永远不要使用四元数出于任何原因。你想要做的事情非常简单。 您所要做的就是调用 transform.Rotate。 就是这么简单。可能是这样的... transform.Rotate(Time.deltaTime, 0, 0); 我尝试使用“transform.Rotate”。不幸的是,我不知道如何插入这种旋转以获得平滑移动。你知道怎么做吗? 【参考方案1】:

大多数示例,包括其官方网站上的 Unity 示例,都以错误的方式使用 Lerp。他们甚至懒得在 API 文档中描述它是如何工作的。他们只是将其添加到 Update() 函数中,然后收工。

Mathf.LerpVector3.LerpQuaternion.Slerp 通过传入 t 值(最后一个参数)从一个位置/旋转到另一个位置/旋转来工作。那 t 值也称为时间。

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

我将用Mathf.Lerp 解释这一点,以便更容易理解。 Lerp 函数对于 Mathf.LerpVectorQuaternion 都是相同的。

请记住,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

如您所见,t(0) 返回传入数字的 mint(1) 返回传入的 ma​​x 值,t(0.5) 将返回minma​​x 值之间的 mid 点。当您传递 < 0> 1 的任何 t 值时,您做错了。 Update() 函数中的代码就是这样做的。 Time.time 每秒都会增加,并且会在一秒钟内变为 > 1,所以你有问题。

建议在另一个函数/协程中使用Lerp,而不是Updated函数。

注意

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

假设我们想从当前的轮换中进行(0,0,90) 的轮换。下面的代码将在 3 秒内将旋转更改为 0,0,90

随时间轮换

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,下面的代码就是一个很好的例子。请理解将对象移动到新的旋转点和仅仅旋转它是有区别的。

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 来使用实时,但需要进行更多计算。

【讨论】:

如果你能帮我解决这个问题我真的很高兴***.com/questions/51066807/… @TenOutOfTen 现在不在我的 Unity 计算机上。当我在它面前时,如果它还没有回答,我会看看这个问题。 好的,已经回答了,但答案不是我需要的方向。【参考方案2】:

在任何事情之前,您不能像这样在欧拉角上添加 180,这主要是导致您的问题的原因。您最好直接使用四元数,或者自己处理转换。

您可以将四元数视为空间中的方向。与之前所说的相反,我建议尽可能学习如何使用它们。但是,我根本不建议使用欧拉角......因为它们受制于不同的书写约定,并且有时会失败。如果您想了解详细信息,可以查看“万向节锁”。

简单地说,slerp 或 lerp(分别代表球面线性插值或线性插值)是一种在方向之间进行插值(从一个方向到另一个方向,通过将 t 从 0 增加到 1,在协程或其他任何地方)的方法A 和 B。两者的区别在于 slerp 为您提供了从 A 到 B 的最短路径。

最后,当 t = 1 时,lerp(A,B,t) 和 slerp(A,B,t) 会给你 B。

在您的情况下,如果您想立即将空间中的对象旋转到特定方向,我建议您使用 Quaternion.AngleAxis 这是从数学上描述四元数的最先进方式。

如果你想添加一个旋转,比如与你的实际方向成 90°(两者之间没有动画),你可以这样做:

transform.rotation *= Quaternion.AngleAxis(axis_of_rotation, angle) 或使用 transform.rotate (取决于参数,它可以是右乘,或左:局部或世界变换)。

程序员的回答是详细说明如何为您的变换设置动画。但我建议你自己研究四元数,因为它会让你全面了解空间变换。

【讨论】:

以上是关于随着时间的推移旋转游戏对象的主要内容,如果未能解决你的问题,请参考以下文章

相机旋转时游戏对象旋转

随着时间的推移移动游戏对象

从左/右和上/下移动旋转和对象

四元数旋转与旋转矩阵略有不同

树木随着 VR 头戴设备的运动在视觉上“旋转”(Unity)

OpenGL glm旋转