Why comparing float values is such difficult?


I am newbie in Unity platform. I have 2D game that contains 10 boxes vertically following each other in chain. When a box goes off screen, I change its position to above of the box at the top. So the chain turns infinitely, like repeating Parallax Scrolling Background.

But I check if a box goes off screen by comparing its position with a specified float value. I am sharing my code below.

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) {
		} else {
			squareLineNumber = 1;
		GameObject squareLineAbove = GameObject.Find ("Square_Line" + squareLineNumber);

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

As you can see, when I compare vectorOne.y and vectorTwo.y, things get ugly. Some boxes lengthen and some boxes shorten the distance between each other even I give the exact vector values in the code above.

I’ve searched for a solution for a week, and tried lots of codes like Mathf.Approximate, Mathf.Round, but none of them managed to compare float values properly. If unity never compares float values in the way I expect, I think I need to change my way.

I am waiting for your godlike advices, thanks!


The comments state that I need to use an array, I used array in the code below but I still need GameObject.Find functions because how can I find the objects to change their positions in another way?

        Vector2 vectorTwo = new Vector2 (0f, -55f);
		for (int i=1; i<11; i++) {
			GameObject squareLine = GameObject.Find("Square_Line" + i);
			if(squareLine.transform.position.y < vectorTwo.y) {
				GameObject squareLineBelow = null;
				if(i == 10) {
					squareLineBelow = GameObject.Find("Square_Line1");
				} else {
					squareLineBelow = GameObject.Find("Square_Line" + (i+1));
				squareLine.transform.position = (Vector2) squareLineBelow.transform.position + new Vector2(0f, 11f);
			} else {
				squareLine.transform.position = (Vector2) squareLine.transform.position + new Vector2(0f, -0.1f);

This code block remains in Update() function. This works fine but If you think it is not a good approach for performance, please warn me. Thanks.

As I mentioned earlier the problem is not with comparing float values. I’ll explain it to you stepwise.

First use array of gameobjects as public field:

public GameObject[] box;

Now when you have attached the script to a gameobject say a GameManager, you can see in the inspector that you can set the number of GameObjects for box. Set it to 10. Then drag and drop the 10 different squares for each slot in the inspector for box field.

Once you have done that, you now have references to all your boxes in the box array.

Now we need to set boundaries for the box to disappear whenever the box crosses it’s limits. Since, we are worried about vertical scrolling in downward direction only, we’ll use a float for this.

float boundary = -5.0f; // Set the values as per your requirement

Once we have this, we’ll need fixed distance between two boxes.

float boxDistance = 0.2f; // Set this to the distance you want between two boxes

Now, you’ll have to move these boxes in the Update(). I’m assuming that you’re moving them vertically downwards. So, I’ll only post the code to move the box at the top.

void Update ()
     // move the boxes and do whatever you want to

     // if the box moves out of the boundary, place it at the top position
	 // the following logic assumes that only one can move out of the boundary in a single Update
	 for (int i = 0; i < box.length; i++)
		 if(box*.transform.position.y < boundary)*
  •   {*
  •  	 // Get the box index at the top*
  •  	 int topIndex = (i+1) % box.length;*
  •  	 // Place the current box at the top separated by the distance (note: x & z aren't changing)*

box.transform.position = new Vector3(box_.x, box[topIndex].y + boxDistance, box*.z);
Now, it’s fixed. You can now change the code as per your requirements. Also, this is more flexible now. You can add as many boxes you want through the inspector. Make boundary and distance public, and you’ll be able to set them too.
Following image explains the trick: