- Home /
How to detect if two objects are are near eachother?
I want to detect is two objects on a layer or with the same tag are near each other by a certain distance. I am trying to create a system where parts snap together and so do the parts' parents ,but I am getting really confused and I'm not really sure how to tell if the objects are a certain distance away from each other. I can't use on trigger enter because the objects don't have to be exactly touching each other to snap to the other? I need to figure out how to detect their distance from each other so that when they get close enough than I can call the Snap() function ,but then I have to also be able to move them from their snap point without them being stuck in place due to the distance parameter. After I figure this out I'm going to have to figure out how to snap the points together because nothing is working for me. I'm getting really stressed out about all of this. Can anybody help me with my current problem? Thanks for any help at all.
Answer by robertbu · May 07, 2014 at 06:21 AM
In think through your goals, there are a number of issues you'll be facing as you expand beyond two objects, but let's concentrate on the two object issue so you can move forward. One solution will be to simply compare all the snap points on one object to all the snap points on another object. Here is a bit of totally untested code (may not even compile), but it gives you an idea of one way you might solve the problem:
void SnapTry(Transform obj1, Transform obj2) {
Transform[] transforms1 = obj1.FindComponentsInChildren<Transform>();
Transform[] transforms2 = obj2.FindComponentsInChildren<Transform>();
foreach(Transform tr1 in transforms1) {
foreach(Transform tr2 in transforms2) {
if (tr1.tag == "SnapPoint" && tr2.tag == "SnapPoint") {
if (Vector3.Distance(tr1.position, tr2.position) <= threshold) {
//Do whatever to snap them together
}
}
}
}
}
'threshold' will be the maximum distance the snap points can be apart and considered a matched, snapping pair. Note I'm using FindComponentsInChildren() because as you get more complex objects, you will still find all the snapping points on combined pieces. Note this code depends on the snapping points having a unique tag. When two snapping points are snapped together, you need to change the tag. This will prevent already taken snapping points from have a second object try and snap.
Final note about Vector3.Distance(). You will read that it is much more efficient to compare the sqrMagnitude of the two objects rather than a function call that involved an additional square root. Don't believe it...don't disbelieve it,...test it if you are having performance issues. I've been involved in two questions in the last year where I blithely suggested using sqrMagnitude, but the person whose question I answered claimed that Vector3.Distance() was notably faster. I've never run the test. Their results may be situational, or bad measuring techniques. Or they could have been right. There are lots of things that go on under the hood that can impact performance...like interpreted vs. native code.
Alright thank you! One quick question, can I get the raycast find the distance and then store it in a transform variable that updates everytime the Snap Point moves? Or would there be a more efficient way to do this?(You don't have to answer it, it's just an extra question)
The above is the solution for any two objects...whether they are a single object or a compound object. At the next level up, you will need to cycle through all the objects (single or compound) with snap points as children, and for each pair run code similar to above. I don't think Raycasting() is the right solution for finding potential pairs in a 3D environment. You could use Physics.OverlapSphere() to identify candidates.
No, because the spheres have to be near eachother. But thanks for the ideas, I'll think of something.
For anybody who wants to know. In this situation I get 5 less frames dropped with sqr$$anonymous$$agnitude than with Vector3.Distance.
Answer by VIPINSIRWANI · May 07, 2014 at 07:09 AM
Hi NutellaDaddy , I am not sure but may be you can solve your problem with RayCasting in forward direction Once try with Rayasting.
float DISTANCE = 1.0f;
Vector3 fwd = transform.TransformDirection(Vector3.forward);
Debug.DrawRay(Character.transform.position,fwd);
if (Physics.Raycast(Character.transform.position, fwd , DISTANCE))
Action();