Unity math bug or what?

Ok, here is the two functions that are acting up, they have Debug.Log lines.

	void UpdatePosition() {
		
		if (transform.position.y > 0.5)
			CurrentSide = 0;
		if (transform.position.y < -0.5)
			CurrentSide = 2;
		if (transform.position.z > 0.5)
			CurrentSide = 1;
		if (transform.position.z < -0.5)
			CurrentSide = 3;
		if (transform.position.x > 0.5)
			CurrentSide = 5;
		if (transform.position.x < -0.5)
			CurrentSide = 4;

		Debug.Log("Side:" + CurrentSide.ToString() +
			" V:" + transform.position.ToString() + "\n" +
			(-transform.position.y).ToString() + "/" + Dist.ToString() + "+" + 3.ToString() + " = " + ((int)-(transform.position.y / Dist) + 3).ToString());

		
		switch (CurrentSide) {
			default:
			case 0:
				pData.x = (int)(transform.position.x / Dist) + 3;
				pData.y = (int)-(transform.position.z / Dist) + 3;
				break;
			case 1:
				pData.x = (int)(transform.position.x / Dist) + 3;
				pData.y = (int)(transform.position.y / Dist)  + 3;
				break;
			case 2:
				pData.x = (int)(transform.position.x / Dist) + 3;
				pData.y = (int)(transform.position.z / Dist) + 3;
				break;
			case 3:
				pData.x = (int)(transform.position.x / Dist) + 3;
				pData.y = (int)-(transform.position.y / Dist)  + 3;
				break;
			case 4:
				pData.x = (int)(transform.position.y / Dist) + 3;
				pData.y = (int)-(transform.position.z / Dist) + 3;
				break;
			case 5:
				pData.x = (int)-(transform.position.y / Dist) + 3;
				pData.y = (int)-(transform.position.z / Dist) + 3;
				break;
		}
//		pData.x = CurrentX;
//		pData.y = CurrentY;
		pData.side = CurrentSide;
		
		return;
	}

	void UpdateEnteringPosition(Vector3 t) {
		
		if (t.y > 0.5)
			pData.enteringside = 0;
		if (t.y < -0.5)
			pData.enteringside = 2;
		if (t.z > 0.5)
			pData.enteringside = 1;
		if (t.z < -0.5)
			pData.enteringside = 3;
		if (t.x > 0.5)
			pData.enteringside = 5;
		if (t.x < -0.5)
			pData.enteringside = 4;
		Debug.Log("eSide:" + pData.enteringside.ToString() +
			" V:" + t.ToString() + "\n" +
			(-t.y).ToString() + "/" + Dist.ToString() + "+" + 3.ToString() + " = " + ((int)-(t.y / Dist) + 3).ToString());
		
		switch (pData.enteringside) {
			default:
			case 0:
				pData.enteringx = (int)(t.x / Dist) + 3;
				pData.enteringy = (int)-(t.z / Dist) + 3;
				break;
			case 1:
				pData.enteringx = (int)(t.x / Dist) + 3;
				pData.enteringy = (int)(t.y / Dist)  + 3;
				break;
			case 2:
				pData.enteringx = (int)(t.x / Dist) + 3;
				pData.enteringy = (int)(t.z / Dist) + 3;
				break;
			case 3:
				pData.enteringx = (int)(t.x / Dist) + 3;
				pData.enteringy = (int)-(t.y / Dist)  + 3;
				break;
			case 4:
				pData.enteringx = (int)(t.y / Dist) + 3;
				pData.enteringy = (int)-(t.z / Dist) + 3;
				break;
			case 5:
				pData.enteringx = (int)-(t.y / Dist) + 3;
				pData.enteringy = (int)-(t.z / Dist) + 3;
				break;
		}

		return;
	}

And here is the console output I get:
UpdateEnteringPosition:

eSide:3 V:(0.0, 0.4, -0.6)
-0.4/0.2+3 = 2

UpdatePosition:

Side:3 V:(0.0, 0.4, -0.6)
-0.4/0.2+3 = 1

UpdateEnteringPosition’s math is incorrect, but UpdatePosition is correct. UpdateEnteringPosition is called from inside a CoRoutine, UpdatePosition is not. Also, UpdatePosition is called after the CoRoutine ends.

For whatever reason, in UpdateEnteringPosition’s switch statement, case zero works fine, but all over cases seem to give bad numbers.

What is going on here?!

Wow that’s freaky.

Have you tried to simply it into an easily reproducible test case?

I’m not sure, but it may be your cast to int:

(int)(t.x / Dist) + 3;

Floating point calculations always have small rounding errors and a cast like (int) 1.99999 returns one where (int) 2.00001 will return 2. Try using Mathf.RoundToInt(t.x / Dist) instead.

Good advice, don’t cast to int unless you specifically want to junk everything after the decimal, (not even as a substitute for Mathf.Floor, which won’t act the same as (int) with negative numbers).

Also don’t ever divide a number by an int unless you specifically want an int quotient. IE. 4/2 = 2, 4/3 =1. Whereas 4/2f = 2, 4/3f = 1.333333f

Also don’t do this:

if (t.y > 0.5)

As you are comparing Vector3.y, which is a float with 0.5 which in C# is a “double”. You have to put an “f” after all decimal number to ensure the compiler reads them as a float… I don’t know how Unity works, but Visual Studio would flag that line of code as an error. (Even though Unity is obviously compiling it for you.

is not an error and compiles fine without even a warning, but something like this

is a real error.

Thank you guys, your code advice worked perfectly.

Even though it didn’t raise an error, I still postfixed an F to the end of each decimal number in the if statements.

And then I also used Mathf.RoundToInt.

Up until now, I had been using only UpdatePosition and casting to an Int and never saw any bugs, but this variation in reaction between transform.position and a Vector3 object is rather interesting.