Comparing 2 Vector3 in 3.5 is flawed???

Hi,
i’m comparing 2 Vector3 using the != operator (i know it’s overloaded for this class)
But the comparison always returns true even if they are equal!
This is my code:

Vector3 v1=agent.destination; // Coming from a NavMeshAgent
Vector3 v2=target.transform.position; //This is the target for my navigation object, just a gameobject
if (v1!=v2){
	Debug.Log ("Pos changed "+agent.destination+" "+target.transform.position+" "+Time.time);
}

And the output in the console is:
Pos changed (-36.8, 0.2, 16.8) (-36.8, 0.2, 16.8) 76.07421

As you can see the vectors are equal but they are evaluated as non equal , and the documentation says the comparison is rounded so it should work even if the vectors are really close (what is really close anyway?).
it looks like it’s comparing instances instead of the value of the vector (could this be possible?)

This is killing me, please some light on this!
Thanks

Interesting ‘bug’ - because as you point out the docs do say:

“Very close vectors are treated as being equal.”

It’s a possibility that their definition of ‘very close’ relies on more significant figures than presented in this scenario - or that this funcitonality is broken.

Regardless of cause - you should be doing this:

Vector3 v1=agent.destination; // Coming from a NavMeshAgent
Vector3 v2=target.transform.position; //This is the target for my navigation object, just a gameobject

if (Vector3.Distance(v1,v2) > 0.01f) {
    Debug.Log ("Pos changed "+v1+" "+v2+" "+Time.time);
}

[untested]

That’s my point, if they are treated as equals then v1!=v2 should be false, not true like in my case!
I still think this is a bug :slight_smile:

If you think it’s a bug… the first thing to do is figure out how different your Vector3’s are - because as I’ve mentioned there could be a small but significant difference. I’m not going to do any tests myself, but based off of this: http://pastebin.com/yW0RNkJv

The first test I’d run would be along the lines of:

print(Vector3.Distance(v1,v2).ToString("G20"));

Thanks for your help NPSF3000 (cool nick),
my two vectors are in fact equals, as you can see from the console:
v1=(-36.8, 0.2, 16.8)
v2=(-36.8, 0.2, 16.8),
so the test v1!=v2 should always be false (since v1 is equal to v2) hence the program should never print in the console like it does.
Doing the distance works fine, but i think Unity should fix the == and !=operator for Vector3 (i still think it’s a bug)

If you think it’s a bug, file a bug report.

That would seem to be a bug (file a bug report, as has been said). However, in practice, it should never be one you encounter because you should never compare floats (or 3 floats, which is what a Vector3 is) in that manner. Always use a distance or squared distance to determine closeness to some key point.

David

Thanks folks, i just wanted to confirm the issue, i don’t want to report false bugs.
Regards

It’s generally a bad idea to make != not be a direct opposite of ==, and it’s also bad to make == not be transitive. i.e. (a==b) (b==c) should imply (a==c). For this reason, a fuzzy operator== is usually not a good idea.

However, it looks like Unity still does this. A quick test shows that the threshold seems to be around 0.00001f times the numbers being compared.

Note that the string representation of Vector3 doesn’t display the numbers with much precision. Don’t use that as the final word on whether they really are equal. Format and print the X, Y, and Z coordinates yourself, to be sure.

It’s not a bug.

That just tells you the precision to the first decimal place; that doesn’t mean they are equal. Print out the .x, .y, and .z values separately.

–Eric

I really wouldn’t trust any form of float equality test, it has always ended in tears. I generally just do greater than or less than tests.

Thanks eric,
they should be identical, i know the console is just a representation, but in fact the two vectors start as the same (i set navmeshagent.destination=target.location) and then during the lifetime i ask if the target has moved (comparing it with the original navmeshagent.destination) which it doesn’t, so they should be identical copies.
Thanks guys for all your good answers!

“Should be” doesn’t mean much. :wink: Print out the real values and see what you get.

–Eric

No, all the console says is that it’s accurate to 3 significant figures [or 1 decimal place].

Floats have around 7 significant figures - so a difference on the 5th significant figure [particularly if it’s amplified by Distance math etc] could be greater than the difference U3D allows. In short - the default ToString is inaccurate and using that for precise calculations [e.g. comparison of floats] is flawed.

Before you can claim it’s a bug you have to first have a good understanding of how to compare floats, and then actually demonstrate that the two floats ARE near identical.