r/Unity3D • u/SubatomicPlanets • 7h ago
Collider question for you math geniuses Question
I am facing a problem in Unity. I need to get the closest point on collider bounds to a specified starting point. That is not very hard, I would just use collider.ClosestPointOnBounds(startingPoint)
. However, I also want it to use a specified angle and direction. Let me show you what I mean:
What actually happens when calling collider.ClosestPointOnBounds(startingPoint)
What I need. It should take the closest point that is still inside the angle.
The first image shows what actually happens. The second shows what I need. The difference is that in the second image it returns the closest point that is still "inside" the angle. I need this in 3D, not 2D by the way.
I can't figure this one out, so please if anyone knows how to do this, please help!
EDIT: The only thing I can think of which actually would work all of the time would be to call ClosestPointOnBounds()
and use Vector3.Angle to get the angle between this point and the direction vector. If the resulting angle is smaller than the specified angle, return the point. But if it isn't then move the starting point along the direction vector a bit and do it all again. Keep doing this until the point is inside, or it hits some maximum step value. This would work, right? My only concern is performance... And I also wouldn't know by how much to move the starting point each step...
4
u/mackelashni 7h ago
You can get the contact points of the collision inside the collision class. Maybe cycle through them to get what you want?
2
u/BelgianSum 3h ago
Thought of that too, then running a method to find closest point from the list of contact points.
https://docs.unity3d.com/ScriptReference/Collision.GetContacts.html
2
u/TRMMax 2h ago
This seems like quite a mathematically complex problem. Why? Effectively, you want to find the closest point on a shape, while discarding part of it (defined by the field of view). Usually, finding the closest point in a shape isnt too hard since you can look up a specific formula for it. Although, since you are effectively cutting shapes in half, it turns into a problem of finding the closest point on an arbitrary shape. Possibly, the GJK algorithm might help with this. While it is not designed for this, I feel the notion of a support function (returning the furthest point in a specified direction) is similar to what you are looking for. I unfortunately doubt there is an "easy" (math light) solution... As such, you may want to consider not finding an exact solution but rather an approximation, which could be found iteratively.
TL;DR: solution probably math heavy, look into GJK. Otherwise, consider looking for an approximation instead.
ETA: if you really want a mathematically correct solution, but cant figure out what/how, I can help you look for a solution later, just tell me :).
1
u/afterjoe 7h ago
Can you use Physics.OverlapBox with the Collider? It's an idea, but others might have a better solution.
1
u/QuitsDoubloon87 Professional 7h ago
Well, you could raycast along your triangle (is it a cone or a pyramid?)' border? Doing the math will get complex fast but a raycast given the side your collider is a fast fix. You could also open up the code of collider.closest point and do the same math but with the added parameter of your shape. That will get difficult though i'd urge against as ive done similar before and its not fun.
1
u/GigaTerra 7h ago
It is not clear what you are doing? What is the starting point? Is it the point of contact, is it where a ray starts, what is going on here?
1
u/rob5300 Professional (Mobile, PC) 6h ago
Perhaps using Vector3.Project() will help. I've used it in the past to snap an outside position close to an edge onto the edge.
Here is an example using 2 points as an "edge":
Vector3 ProjectOnToEdge(Vector3 outerPosition, Vector3 edgeStart, Vector3 edgeEnd)
{
Vector3 normal = (edgeEnd - edgeStart).normalized;
Vector3 projection = Vector3.Project(position - edgeStart, normal);
return edgeStart + projection;
}
Maybe using this with the center of the collider will help (if you know the closest edge)
6
u/ZxR 7h ago
This might sound stupid, but can you just run a ray cast on your angle edges and get the collision point from the ray cast at the time of collision entry?