需要以特定方式旋转物体 - 坚持使用万向节锁?

时间:2018-06-14 21:01:59

标签: unity3d rotation quaternions euler-angles

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

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

我整天都在阅读Quaternions和Euler角度,但我仍然不完全确定我的问题是什么。

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

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

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

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

}
}

1 个答案:

答案 0 :(得分:2)

使用Transform.RotateAround

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

但是使用RotateAround,您可以传入全局UpLeftForward向量,这就是您要尝试的内容。