Vector3 Equals not working

Im trying to compare 2 Vector3 vars in method Update. Sometimes method Contains/Equals/== not working.

List Vector3 newPositions - local var

List Vector3 oldV - global var

Using mono debug:


why that happens?


void Update () {



protected void FillSky() {
	int partsCount = widthPartsCount * heightPartsCount;
	Vector3 firstElementPos = FirstElementPosition();

	if (firstElementPos != lastUpdatedPosition) {
		lastUpdatedPosition = firstElementPos;

		List<Vector3> newPositions = new List<Vector3>(partsCount);

		for (int i = 0; i < widthPartsCount; i++) {
			for (int j = 0; j < heightPartsCount; j++) {
				Vector3 go_size = skyPrefabPrototype.transform.localScale;
				float goX = firstElementPos.x + go_size.x / 2f + go_size.x * i;
				float goY = firstElementPos.y + go_size.y / 2f + go_size.y * j;
				Vector3 go_pos = new Vector3(goX, goY, 0f);

		List<Vector3> toCreate = new List<Vector3>();
		List<GameObject> toDestroy = new List<GameObject>();

		bool haveParts = parts.Count > 0;

		for (int i = 0; i < newPositions.Count; i++) {

			Vector3 nv = newPositions*;*
  •   		if (haveParts) {*
  •   			GameObject go;*

_ go = parts*;_
if (!newPositions.Contains(go.transform.position))_

* go = parts.Find(delegate(GameObject obj) {*
* return obj.transform.position == nv;*
* });*
* if (!go)*
* toCreate.Add(nv);*
* } else {*
* toCreate.Add(nv);*
* }*
* }*

* foreach (var go in toDestroy) {*
* parts.Remove(go);*
* Destroy(go.gameObject);*
* }*
* foreach (var v in toCreate) {*
* GameObject go = (GameObject)Resources.Load(SKY_PREFAB_NAME);
go = (GameObject)Instantiate(go, v, Quaternion.identity);_
// TODO*_
* // set texture here*
* parts.Add(go);*
* }*
* }*
* }*

I’ll leave my original answer, snide parts about not posting code removed ;), for others in case they have that issue, but I believe your issue is that you’re using Contains to check if one vector is equal to another vector, but you can’t do that because the = operator of vectors create new vector instances. I can’t find specific documentation to show that the = operator is indeed always creating a copy, but I’m concluding it from observation. Contains looks for the reference of one object equal to the reference of another object, not the values of those objects. Basically, if Vector3 can’t be passed by reference to another Vector3, then you simply can’t use Contains on the Vector classes. We could verify this to be certain by printing out the address of the Vector3 stored in the list and the other one you are comparing it to.

In other words, adding a Vector3 object to the list will create a new Vector3 object in that list and copy the values from yours into it. That’s what it appears to be doing anyway. When you pull that Vector3 out later, it will create yet another copy and put the data from the list instance into your copy. Checking List.Contains(someOtherVector) will be testing a reference of the local version against the reference of the version inside the list, and it will always be false. Another verification of this is to create a new Vector3, assign some value to it, add it to the list, then pull it out of the list into a new instance, modify it, and see if the original vector3 was modified. I’m pretty certain it won’t be, but I’ll give it a try later if I have time.

Old post: You may be trying to compare two vectors that are made of up floating point values, and you should not compare floating point values, because they will almost never be the same (unless you explicitly set them to the same value).

However, according to this:

if you are using that operator, then Unity will return true if they are “really close”. What that means is anyone’s guess, and I wouldn’t trust that. If you want to be sure your two vectors are “near” one another, the fastest way is to take the absolute value of the difference of their squared magnitudes, and create some threshold within which that difference is acceptable.

float diff = Mathf.Abs(myVector1.sqrMagnitude - myVector2.sqrMagnitude);
if (diff < 10)
    // Close enough