- Home /
[Solved] Problem Finding Closest GameObject to Cursor Point
I have a bit of a problem with a game I'm making. Basically, I have a plane with a grid of empty GameObject's parented to a mesh, and when the user clicks the mesh somewhere, I want to pull the closest empty to the cursor point. Currently, I have a Raycast hitting objects and I get the point back correctly from the mesh's collider and everything. The problem lies in the part where I actually calculate the closest GameObject. Essentially, it is always giving me the same empties as closest to the point, no matter where I click on the mesh.
Dictionary<GameObject, float> distances =
new Dictionary<GameObject, float>();
foreach (var empty in meshGameObjects)
{
float distance = Vector3.Distance(cursorVector3,
empty.transform.position);
distances.Add(empty, distance);
}
distances = distances.OrderBy(pair => pair.Value).ToDictionary(pair =>
pair.Key, pair => pair.Value);
Debug.Log("Closest is: " + distances.First(pair => pair.Key));
Debug.Log("Second closest is: " + distances.ElementAt(1));
return closest;
Note that the cursor hit point is also being passed into this method after being transformed to the local scale of the empties via calling a InverseTransformPoint from the parent mesh. The only thing I can think of is that this is something to do with the parenting and/or the algorithm I'm using. Perhaps it would be better to pick a random default empty to transform the point from world to the empties' local space instead of using the parent meshes' transform?
Thanks for any help! Sorry if the code is a bit messy--I wrote it by memory and I apologize for any errors in advance. If I left out an important part, just tell me and I'll get to adding it!
Edit: Sorry about the messy code. I cleaned it up a bit to make it easier to read on Unity Answers.
Turns out that the original problem was not related to this at all!
Answer by nixcs2512 · Aug 06, 2013 at 07:41 AM
If you only want to find the closest object, there is another way ( i think more easy to understand ):
...
float closestdistance = Mathf.Infinity;
GameObject closestObject;
foreach (GameObject empty in meshGameObjects)
{
float distance = Vector3.Distance(cursorVector3,empty.transform.position);
if(distance<closestdistance) // or <= ,i will explain 2 cases.
{
closestdistance = distance;
closestObject = empty;
}
//when for loop ended, the closestObject is the one you need.
...
}
The different with <(1) and
//when for loop ended,...
List<GameObject> closestList = new List<GameObject>();
foreach (GameObject empty in meshGameObjects)
{
float distance = Vector3.Distance(cursorVector3,empty.transform.position);
if(distance == closestdistance)// or (distance.Equals(closestdistance))
closestList.Add(empty);
}
//all closest GameObjects now in closestList
Thanks for the suggestion. Interestingly enough, the same two empties are still being returned as the closest no matter where I click on the mesh. Do you think this would be a problem related to the actual method behind finding it, if both of our algorithms don't seem to work? I'm going to try some other things and see what I come up with.
Your method does seem to be a bit cleaner, but $$anonymous$$e is a bit more straightforward (in my opinion). I'm essentially collecting all the distances and then ordering them with .NET methods. On the other hand, you are iterating over the objects and trying to find the closest one by comparison. I'll probably stick with my method since I'm generally a fan of LINQ though. I might test performance later if I need to find the closest out of hundreds--not tens--of empties.
Oh, and I forgot to mention another reason for keeping the list of closest values--I need them in order, in case one of them is "invalid", I need to find the "second closest" one out of the list. That part seems to be working though.
So my code and your code always returns the same result? Did you try to print out all the distances and exa$$anonymous$$e? The performance now is not a problem, only need to solve it . And it's always my rule : "if the problem has any answer,i will solve it at all cost" :)
@nixcs2512 Yes, yes, I'm familiar with the premature optimization evil that plagues us all. ;)
Yes, it's really odd. I don't understand it honestly. Originally I thought it was a problem with the algorithm itself, but I'm beginning to think it might be some discrepancy in the scale of the Vector or the parenting of the empties to the mesh. I'm going to mess around with those values and see what comes out of it.
@QuantumCD If still no luck, try to find another way for your game, i remember one thing that i heard : " Sometimes rebuilding is a better way than fixing " (i'm not good at English so hope you can get it). Anyway good luck with your job :)
Your answer
Follow this Question
Related Questions
transform.Transform Direction Help! 0 Answers
transform Vector3 help! 2 Answers
Distribute terrain in zones 3 Answers
Multiple Cars not working 1 Answer
The name 'Joystick' does not denote a valid type ('not found') 2 Answers