为什么比较浮点值如此困难?

Why comparing float values is such difficult?

我是Unity平台的新手。我有一个 2D 游戏,其中包含 10 个垂直排列的盒子。当一个盒子离开屏幕时,我将其位置更改为顶部盒子的上方。所以链条无限转动,就像重复视差滚动背景。

但我通过将框的位置与指定的浮点值进行比较来检查框是否离开屏幕。我在下面分享我的代码。

void Update () {
    offSet = currentSquareLine.transform.position;
    currentSquareLine.transform.position = new Vector2 (0f, -2f) + offSet;

    Vector2 vectorOne = currentSquareLine.transform.position;
    Vector2 vectorTwo = new Vector2 (0f, -54f);

    if(vectorOne.y < vectorTwo.y) {
        string name = currentSquareLine.name;
        int squareLineNumber = int.Parse(name.Substring (11)) ;
        if(squareLineNumber < 10) {
            squareLineNumber++;
        } else {
            squareLineNumber = 1;
        }
        GameObject squareLineAbove = GameObject.Find ("Square_Line" + squareLineNumber);

        offSet = (Vector2) squareLineAbove.transform.position + new Vector2(0f, 1.1f);
        currentSquareLine.transform.position = offSet;
    }
}

如您所见,当我比较 vectorOne.y 和 vectorTwo.y 时,情况变得很糟糕。即使我在上面的代码中给出了确切的向量值,有些盒子也会拉长,有些盒子会缩短彼此之间的距离。

我已经搜索了一个星期的解决方案,并尝试了很多代码,例如 Mathf.Approximate、Mathf.Round,但其中 none 成功地比较了浮点值。如果 unity 从来没有按照我期望的方式比较浮点值,我想我需要改变我的方式。

期待各位大神指教,谢谢!

编辑

这是我的屏幕。我有 10 条垂直向下的框线。

当 Square_Line10 离开屏幕时。我将它的位置更新到 Square_Line1 以上,但它们之间的距离意外增加。

试试这个解决方案:

bool IsApproximately(float a, float b, float tolerance = 0.01f) {
    return Mathf.Abs(a - b) < tolerance;
}

原因是内部比较中的公差不好用。如果您需要更高的精度,请将函数调用中的公差值更改为更低。

好的,我找到了一个非常有效的解决方案。

我需要使用数组并在两个 for 循环中检查它们。第一个移动盒子,第二个检查盒子是否离开屏幕,如下所示

public GameObject[] box;
float boundary = -5.5f;
float boxDistance = 1.1f;
float speed = -0.1f;

// Update is called once per frame
void Update () {
    for (int i = 0; i < box.Length; i++) {
        box[i].transform.position = box[i].transform.position + new Vector3(0, speed, 0);
    }

    for (int i = 0; i < box.Length; i++)
    {
        if(box[i].transform.position.y < boundary)
        {
            int topIndex = (i+1) % box.Length;

            box[i].transform.position = new Vector3(box[i].transform.position.x, box[topIndex].transform.position.y + boxDistance, box[i].transform.position.z);
            break;
        }
    }
}

我把它附加到 MainCamera。