0

最后一天,我一直在思考如何计算一个完整的旋转,以及如何使用 SteamVR 的基本圆形驱动器计算一个物体沿 X 轴的完整旋转。

我认为一个简单的 3d 立方体,在旋转路径中关闭网格并带有碰撞代码将是一种准系统的方式,但它似乎甚至没有在物体撞击时注册检测放置立方体,我知道这不是因为我很愚蠢,因为它从项目的工作部分回收了代码。

下面我有一小段代码,它基本上检测对象何时到达旋转结束,然后将 Count 加一。

我的主要问题是有时它会多次计时,如果你能找到正确的位置,你可以把它留在那里,它会继续增加计数。我想知道如何停止它并只增加一个,直到完成另一个完整的旋转?

编辑:为了更清楚,以防有任何混淆,一旦角度在 359 和 360 之间,我希望它增加一次,而目前如果你让角度坐在 359-360 之间的任何地方,它将继续尽管没有进行完全旋转,但在旋转计数中加一,所以我试图弄清楚如何让我的代码只增加一次,一旦将位置重置为零,它就会增加一次,因此不会再发生增量. 它是 VR 中沿 X 轴的曲柄机构。

任何帮助表示赞赏,谢谢!

 float Test;

float RotationCount = 0;

// Start is called before the first frame update
void Start()
{
   //  Test = transform.localRotation.eulerAngles.x;


}

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

    if (Test > 359 && Test < 360)
    {
        Debug.Log("Clocked");
        count();
    }
    else
    {
      //  Debug.Log("Nope");
    }


    if (Test == 0)
    {
        Debug.Log("Yes");
    }

    Test = transform.localRotation.eulerAngles.x;

}

void count()
{

    RotationCount++;

}
4

1 回答 1

0

有时它会多次计时,如果你能找到正确的位置,你可以把它留在那里,它会继续增加计数。

很好

if (Test > 359 && Test < 360)
{
    Debug.Log("Clocked");
    count();
}

如果你的角度是 eg 会发生什么359.5

仅采用当前的旋转并知道它是否转动了大于或小于某个角度是非常困难的。


我宁愿存储最后一次旋转,将其与当前旋转进行比较并将差异添加到变量中。比如果变量超过360一个完整的旋转完成。由于我也不喜欢用Quaternionand计算任何东西eulerAngles,所以更简单的方法是使用Vector3.

对于围绕X(== transform.right) 的局部旋转,我将使用当前向量和最后一个transfrm.up向量之间的角度。

就像是

public class RotationCheck : MonoBehaviour
{
    public int RotationCount;

    public float rotatedAroundX;

    public Vector3 lastUp;

    public UnityEvent On3TimesRotated;

    private void Awake()
    {
        rotatedAroundX = 0;

        // initialize
        lastUp = transform.up;
    }

    private void Update()
    {
        var rotationDifference = Vector3.SignedAngle(transform.up, lastUp, transform.right);

        rotatedAroundX += rotationDifference;

        if (rotatedAroundX >= 360.0f)
        {
            Debug.Log("One positive rotation done", this);

            RotationCount++;

            rotatedAroundX -= 360.0f;
        }
        else if (rotatedAroundX <= -360.0f)
        {
            Debug.Log("One negative rotation done", this);

            RotationCount--;

            rotatedAroundX += 360.0f;
        }

        // update last rotation
        lastUp = transform.up;


        // check for fire the event
        if (RotationCount >= 3)
        {
            On3TimesRotated?.Invoke();

            RotationCount = 0;
        }
    }
}

您可以使用UnityEvent来获得相同的Button用途,onClick以便您可以通过检查器引用回调。

在此处输入图像描述


但是,如果您不关心单次旋转,但实际上只在决赛中RotationCount >= 3,我实际上会使用

private void Update()
{
    var rotationDifference = Vector3.SignedAngle(transform.up, lastUp, transform.right);

    rotatedAroundX += rotationDifference;

    RotationCount = Mathf.RoundToInt(rotatedAroundX / 360.0f);

    // update last rotation
    lastUp = transform.up;


    // check for fire the event
    if (RotationCount >= 3)
    {
        On3TimesRotated?.Invoke();

        RotationCount = 0;
        rotatedAroundX = 0;
    }
}

如果在 360 标记下旋转,则直接将值减一,而不是等待完整的负旋转

在此处输入图像描述

*如您所见,它不是达到 3,RotationCount而是重置为 0。这是On3TimesRotated事件被/将被触发的地方。

于 2019-04-01T11:41:33.923 回答