【问题标题】:Need to rotate object in specific ways - Stuck with Gimbal Lock?需要以特定方式旋转对象 - 卡住了万向节锁?
【发布时间】:2018-11-24 17:26:26
【问题描述】:

我正在开发一个小型迷你游戏,它需要根据您滑动的方向将立方体在适当的方向上旋转 90 度。所以你可以向上滑动,它会向上旋转 90 度,然后它们立即向左滑动,它会从你当前的旋转向左滑动 90 度(所以它也会保持向上旋转 90 度)。我觉得这应该很简单,但这给我带来了很多麻烦。

我想使用 Lerp/Slerp 以使旋转看起来不错,尽管这不是完全必要的。我目前实现它的方式,例如,每次我调用我的“SlerpRotateLeft()”函数时,它每次只旋转到相对于世界完全相同的旋转(而不是当前旋转 + 90 度在正确的方向)。

我整天都在阅读四元数和欧拉角,但我仍然不完全确定我的问题是什么。

我目前正在使用状态来确定对象当前正在旋转的时间和方向,尽管我觉得我可能过于复杂了。此问题的任何可能解决方案(您可以在特定方向上以任何顺序连续滑动,以将立方体在该特定方向上旋转 90 度)。以前,我尝试使用协程,但也没有达到预期的效果(而且我无法重置它们)。

这是我的课。它可以工作,您可以通过将脚本放入编辑器中的任何多维数据集对象来测试它,但它不能按预期工作。通过测试你会看到我的问题是什么(我建议在立方体的正面放置一个图像来跟踪它是哪一个)。我不确定我是否正确解释了我的问题,所以如果需要更多信息,请告诉我。

****更新:我已经接受@Draco18s 的回答是正确的,因为他们的解决方案有效。但是,我并没有完全理解解决方案,或者如何存储值。我找到了一个类似问题的答案,该问题也使用了 Transform.Rotate,并存储了值,这有助于理清解决方案。关键似乎是将它存储在 GameObject 中,而不是像我最初想的那样存储在四元数中。我认为我应该提供此代码,以防有人偶然发现并同样感到困惑,尽管您可能不需要滑动检测:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Rotater : MonoBehaviour
{

 private GameObject endRotation;


//SWIPE VARIABLES
public Vector2 touchStart = new Vector2(0, 0);

public Vector2 touchEnd = new Vector2(0, 0);

public Vector2 currentSwipe = new Vector2(0, 0);

public Vector2 currentSwipeNormal = new Vector2(0, 0);

// Use this for initialization
void Start()
{
    endRotation = new GameObject();

}

// Update is called once per frame
void Update()
{


    if (Input.GetMouseButtonDown(0))
    {
        touchStart = new Vector2(Input.mousePosition.x, Input.mousePosition.y);
        //Debug.Log("Touched at: " + touchStart);

    }

    if (Input.GetMouseButtonUp(0))
    {
        touchEnd = new Vector2(Input.mousePosition.x, Input.mousePosition.y);

        //Get Swipe Vector information
        currentSwipe = new Vector2(touchEnd.x - touchStart.x, touchEnd.y - touchStart.y);

        //Normalize Swipe Vector
        currentSwipeNormal = currentSwipe;
        currentSwipeNormal.Normalize();

        //Swipe up
        if (currentSwipeNormal.y > 0 && currentSwipeNormal.x > -0.5 && currentSwipeNormal.x < 0.5)
        {
            endRotation.transform.Rotate(-Vector3.left, 90, Space.World);

        }
        //Swipe down
        if (currentSwipeNormal.y < 0 && currentSwipeNormal.x > -0.5 && currentSwipeNormal.x < 0.5)
        {
            endRotation.transform.Rotate(Vector3.left, 90, Space.World);


        }
        //Swipe left
        if (currentSwipeNormal.x < 0 && currentSwipeNormal.y > -0.5 && currentSwipeNormal.y < 0.5)
        {
            endRotation.transform.Rotate(Vector3.up, 90, Space.World);



        }
        //Swipe right
        if (currentSwipeNormal.x > 0 && currentSwipeNormal.y > -0.5 && currentSwipeNormal.y < 0.5)
        {
            endRotation.transform.Rotate(-Vector3.up, 90, Space.World);

        }

    }

    LerpRotate();
}

void LerpRotate()
{
    transform.rotation = Quaternion.Lerp(transform.rotation, endRotation.transform.rotation, Time.deltaTime * 10);

}
}

【问题讨论】:

    标签: unity3d rotation quaternions euler-angles


    【解决方案1】:

    使用Transform.RotateAround

    您遇到的问题是,您采用当前欧拉角并尝试加/减 90,由于旋转参考系的旋转性质,这不一定与所需位置相关。

    但是使用 RotateAround,您可以传入全局 UpLeftForward 向量,这正是您想要做的。

    【讨论】:

    • 那么我会使用 Transform.RotateAround 代替 Lerping/Slerping 吗?你能举例说明我会改变什么吗?
    • 您可以使用RotateAround 获得所需的旋转,存储四元数,重置变换,然后根据需要进行 slerp。
    • 我尝试将我的 SlerpRotateUp() 函数中的 Quaternion.Slerp 语句替换为“transform.RotateAround(-Vector3.left, 5 * Time.deltaTime);”尽管传递了应该停止调用函数的所需旋转,但它仍然继续旋转。 (它还说 RotateAround 已过时,我应该使用 Transform.Rotate)
    • 您不能通过 (rotation.x == 90) 设置停止点,因为该值是浮点数 90.0000000001 != 90。另外,是的,您可以使用 Transform.Rotate 代替,我忘了它已被弃用。基本上是the same function
    • 现在当我检测到向上滑动时,我设置 currentState = States.Up,设置startingQuat = transform.rotation,并设置destinationQuat = Quaternion.Euler(startingQuat.eulerAngles.x + 90f, startingQuat.eulerAngles.y,startingQuat.eulerAngles.z),当处于 Up 状态时,我检查是否 (transform.rotation != destinationQuat),如果是,我调用 RotateUp();在 RotateUp() 中,我调用 Transform.Rotate。它在前两个旋转中工作正常,但之后,它会无限旋转。恐怕我还是不明白我应该改变什么。
    猜你喜欢
    • 2015-02-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多