- Home /
Dictionary with Vector3 as key cannot be child gameobjects
It appears that there are weird rounding errors if there is a dictionary with keys being Vector3 representing positions of gameobjects that are children of another gameobject.
For such a situation, when you need to check if a hit gameobject is in the dictionary (by position), is there another solution other than to de-parent?
Steps:
Create some pooled gameobjects that are children of a parent object.
Loop through parent transform GetChild to get child objects, and assign each child objet's position as key to the dictionary
Try a raycasthit on any of the child gameobject positions, to see if they are in the dictionary. None will show up!
But, the above works as expected if they are not parented.
Note, assigning parent null, then reassigning old parent does not work
Can you be more explicit about what you're doing and when it fails (or add more details)?
I've had good luck with transform.position of pre-placed editor objects being a struct member, and that struct being a dictionary key.
Please describe the circumstances where it seems that rounding issues may be co$$anonymous$$g into play and what makes it seem that that parenting or not is relevant.
Answer by ArkaneX · Oct 08, 2013 at 08:54 AM
I guess the problem might be related to float numbers rounding, e.g. the Vector3 which is a key might be (1,1,1), while the vector you're using to retrieve value might be (1,1,0.99999999999999999). When checking for existence of key (`dic.ContainsKey(key)`), or when retrieving value by key (`dic[key]`), Equals(object)
method is used, which checks if x, y, and z are exactly the same.
Depending on the number of children, you can try iterating through dictionary, checking keys for equality using == operator. This operator for Vector3 is overloaded, so if two vectors differs slightly, they are treated as equal.
So there is no way to just reference it by dictionary[value]?
I'm afraid not. You can sometimes be able to retrieve the value this way, but not in all cases.
In rare cases, hash codes of slightly different vectors might be the same, but ultimately Equals
method will return false.
You sir just saved me a lot of time! Thanks for your clear explanation. $$anonymous$$y game is one step closer to being complete thanks to you. I was starting to lose faith after googling more than 2 hours for possible reasons for my bug and found this answer! The workaround was to use Vector3Int for comparing it to the dictionary key with TryGetValue.
Answer by IgorAherne · Aug 02, 2017 at 02:30 PM
if you are in situation where you need a dictionary with Keys as Vector3
then, you can create a dictionary with a custom IEqualityComparer:
class Vector3CoordComparer : IEqualityComparer<Vector3> {
public bool Equals(Vector3 a, Vector3 b) {
if (Mathf.Abs(a.x - b.x) > 0.001) return false;
if (Mathf.Abs(a.y - b.y) > 0.001) return false;
if (Mathf.Abs(a.z - b.z) > 0.001) return false;
return true; //indeed, very close
}
public int GetHashCode(Vector3 obj) {
//a cruder than default comparison, allows to compare very close-vector3's into same hash-code.
return Math.Round(obj.x, 3).GetHashCode()
^ Math.Round(obj.y, 3).GetHashCode() << 2
^ Math.Round(obj.z, 3).GetHashCode() >> 2;
}
}
public static Vector3CoordComparer _customComparer = new Vector3CoordComparer ();
public Dictionary<Vector3, someValues> coord_to_values = new Dictionary(_customComparer); //notice, the argument
This solved my problem and the code works perfectly! Thanks a lot!
Your answer
![](https://koobas.hobune.stream/wayback/20220613115523im_/https://answers.unity.com/themes/thub/images/avi.jpg)
Follow this Question
Related Questions
Searching through a text file with Unity? 4 Answers
[JS] String,List dictionary doesn't compile. Any suggestions? 1 Answer
error CS1526: A new expression requires () or [] after type 1 Answer
Better Dictionary? (serializable with more functionality) 1 Answer
Dictionairy Serialization Problem: Keys and values get lost 0 Answers