转换EulerAngles错误

时间:2018-03-13 16:30:56

标签: c# unity3d euler-angles

我有条件进行检查。像这样:

if (moveDown)
        {
            Debug.Log("hit1");
            if (RightTowers[rightIndex].transform.GetChild(2).transform.eulerAngles.z <= -40f)
            {
                moveDown = false;
                moveUp = true;
            }
            else
            {

                RightTowers[rightIndex].transform.GetChild(0).gameObject.GetComponent<SpriteRenderer>().sprite = Mirrors[mirrorIndex++];
                rotateAngle = Quaternion.Euler(0f, 0f, RightTowers[rightIndex].transform.GetChild(2).eulerAngles.z - angle);
                RightTowers[rightIndex].transform.GetChild(2).transform.rotation = rotateAngle;
            }
        }
        if (moveUp)
        {
            Debug.Log("hit2");
            if (RightTowers[rightIndex].transform.GetChild(2).transform.eulerAngles.z >= 40f)
            {
                moveDown = true;
                moveUp = false;
            }
            else
            {

                RightTowers[rightIndex].transform.GetChild(0).gameObject.GetComponent<SpriteRenderer>().sprite = Mirrors[mirrorIndex--];
                rotateAngle = Quaternion.Euler(0f, 0f, RightTowers[rightIndex].transform.GetChild(2).eulerAngles.z + angle);
                RightTowers[rightIndex].transform.GetChild(2).transform.rotation = rotateAngle;

            }
        }

问题是当对象旋转到-40度并且检查了条件时,它不会停用moveDown并激活moveUp。他用角度指数进一步旋转物体。 我点击按钮时进行旋转。当他达到-40度时,他必须停用我的moveDown。为什么不禁用它?

2 个答案:

答案 0 :(得分:0)

首先,创建一些中间字段,您的代码非常繁重,并且由于您正在进行的所有嵌套调用,您每次都实际访问数据,并且它确实使其不清楚,特别是对于项目之外的任何人。

其次,我没有看到2个布尔值与彼此完全相反的价值......由于它们被反转,你只得到一个相同的结果。

话虽如此,我相信(根据我从你的片段中获得的内容),你可能不在你想到的学位范围内?我不知道你是否已经证实了这一点,但是,你的角色看起来完全正常,就像你最初放置他一样,但是他可能会应用360度,720度......旋转角度(也可以是负面的) ,所以如果你没有看到初始位置和期望之间的轮换,你可能得不到正确的值,可能会做RotationDifference() func,或者if (rotation == 360 or -360) rotation = 0我只是抛出想法,你真的有很多方法可以做到这一点。

最后,对于看似平凡的任务,你的代码似乎相当沉重,你应该研究一下。尝试抽象你的任务,你试图一次完成所有事情,而不是让坚固的系统来处理它。

答案 1 :(得分:0)

(评论后的新答案)

你想要的逻辑在阅读代码时并没有“清楚地”出现,这使得调试和理解错误变得困难!

根据您的评论,我了解您需要在-40到40之间来回移动。

首先,我们需要明确区分任务

两个单独的任务是:

  • 决定下一步移动方向塔。

  • 向上或向下移动塔架。这基本上是两个3行代码块。我们称这些块为“MoveUp()”和“MoveDown()”

现在,为它写一些伪代码

// pseudo code

// First, decide in which direction to go
if current angle is 40° (or more), 
    set direction to down for next move. 
else if current angle is -40 (or less), 
    set direction to up for next move. 
else 
    just continue in the current direction

// Second, move the tower
if direction is down, move down
else move up.

让我们将其转换为真正的C#代码

// suppose you have a private bool variable in your class
// called "isMovingDown"
private bool isMovingDown = false; // inital value, could be true if you want

// call this in your Update or FixedUpdate logic
private void MoveYourTowerLogic() {
    // First : decide in which direction to go :
    var currentAngle = RightTowers[rightIndex].transform.GetChild(2).transform.eulerAngles.z;

    if (currentAngle >= 40f) 
    {
        isMovingDown = false;
    }
    else if (currentAngle <= -40f)
    {
        isMovingDown = true;
    }
    // else current angle is between 40 and -40 
    // we simply need to o nothing, because we want to keep the previous direction set.
    // remember, the variable movingDown is declared at the class level, 
    // so it 'remembers' the last value set from last call


    // Second : Move the tower
    if (isMovingDown)
    { 
        MoveDown();
    }
    else // tower is moving up
    {
        MoveUp();
    }
    // NOTE : I would simply create one function Move(int angle)
    // to simplify this much further and avoid to write all this mostly useless code before
    // but I want to keep this simple to understand for now
}

private void MoveDown()
{
    // logic to move tower down
}

private void MoveUp()
{
    // logic to move tower up
}

请注意,现在阅读这篇文章更加“人性化”,我希望您现在可以更轻松地阅读本文,如果您想在以后做更复杂的事情,这将有助于您修改它。

我强烈建议您多次避免编写相同的代码。你可以注意到我如何简化和编写只有一次逻辑才能将角度转换为一个名字,就像我在伪代码中所想的那样。

此外,要编写方法“MoveUp”和“MoveDown”,您只需将实际代码粘贴到其中即可。但之后,您甚至可以重构它们以避免代码重复。

像这样:

(编辑)

让我们进一步重构

基本上,移动逻辑是一个完全独立的任务,向上和向下移动的唯一区别是+或 - 角度。

另外,也许你想稍后用不同的角度移动你的塔。有意义的是,塔的旋转仅取决于角度。

所以让我们创建一个只有角度作为参数的方法。

使用类似的东西,而不是MoveUp()和MoveDown():

private void MoveTower(int angle) 
{
   RightTowers[rightIndex].transform.GetChild(0).gameObject.GetComponent<SpriteRenderer>().sprite = Mirrors[mirrorIndex++];
   rotateAngle = Quaternion.Euler(0f, 0f, RightTowers[rightIndex].transform.GetChild(2).eulerAngles.z + angle);
   RightTowers[rightIndex].transform.GetChild(2).transform.rotation = rotateAngle;
}

第二部分将更加简单:

    // Second, move the tower
    MoveTower(isMovingDown ? angle : -angle);