Hello,
I have a question. I want to write a function where I have a car, and a bunch of way points. I only want the car to pick way points that are NOT ONLY in front of the car, but ALSO IF the way points are pointing in a certain range of direction similar to the direction of where the car is pointing.
In my function, I want it to return anywhere from +1.0f (IF the blue arrow in my editor from the waypoint is pointing in the EXACT SAME direction of where the blue arrow is pointing from the car AND, if the way point is in front of my car), and a -1.0f (IF the waypoint is EITHER behind the car OR in front of the car BUT the blue arrow in my editor is pointing in the wrong direction). How would I achieve this? Thank you.
If the angle between your carâs forward direction (transform.forward) and the position of the waypoint relative to your carâs position (waypoint.position - transform.position) is less than 90, it is in front. More than 90, it is behind.
Then you only need to map the angle to a -1,1 float range.
Iâll come up with an example and post back here.
Yes and no.
First of all the Dot product only returns a value between -1 and 1 if both vectors are normalized, otherwise it doesnât. Also while it is true that they return a value of 1 if they point exactly in the same direction and -1 if they face exactly in opposite directions, itâs not a linear relationship in between. Itâs actually the cosine of the angle between the two vectors. Yes, itâs the cheapest solution and if youâre only interested if something faces âroughlyâ in the same direction or roughly in the opposite direction, the dot product is the way to go. However when you need an actual smooth gradient, using Vector3.Angle and remap is the better solution.
Note that in most cases itâs very unlikely to actually get a value of 1 or -1 from the dot product (when using two normalized vectors). Likewise an exact angle of 0° or 180° is also quite unlikely, so always work with ranges.
I guess you need that value to actually rotate a âhint arrowâ for a driving game? Since you talked about the forward axis of your waypoint, I guess you rotated the waypoints so their forward axis points in the direction where you need to go fro here. So you usually would calculate two values. The first would tell you if youâre heading towards the waypoint or away from it. The second value would tell you if you have the same alignment as the waypoint. You just have to mix the two values based on how far you are from the waypoint. If you are far away from your next waypoint, you usually only care about the direction towards the waypoint and not the direction where to go from that waypoint. The closer you get to the waypoint, the more important the forward direction of the waypoint gets. When you are really close, that forward direction is the only relevant direction. Likewise you could also incoperate the last waypoints forward direction and use that if you are still closer to the last waypoint and slowly move over to use the next way point. So just a bunch of slerps depending on the relative distances.
Note if that hint arrow is your actual goal, using an angle directly would probably make more sense. Though I would use a SignedAngle instead so you also know the direction (left or right).
Of course so far as the OP is concerned they would query each waypoint and check which one is the closest to one and in front. Nothing is exact with floating point calculations, we should all know the caveats of them as programmers.
Now what we havenât answered is how to tell if the waypoint is in front of the car, which is basically transform.InverseTransformPoint and if z is greater than 0 itâs in front.
Oh and direction like tranform.forward is already normalized so that point is moot. Vector3.Angle/SignedAngle probably normalizes both vectors anyways, even though it isnât really needed. (The Unity API does do some redundant things to make up for newbs.) Yeah I know thatâs an assumption and I could be wrong, I have been before and will be again.
I think I developed my own formula. The obj variable is the waypoint, and the âthisâ variable refers to the car. CalculateValidWaypointAngle returns between 0 and 1 depending on IF the waypoint should be considered (depending on where the waypoint is facing). getFacingValue returns between 0 and 1 if the car is facing toward or away from the waypointâŚ
If angle was to equal 0, this line might throw a âCannot devide by zeroâ error.
I prefer to avoid divisions as much as possible, and instead multiply by a float.
/ 2 is equavalant to * 0.5f / 180 is equavalnt to * 0.0055f
When you do this you guarantee that the calulation is safe against division by zero errors if the varible youâre halving ever happens to equal zero. Although you may loose some precision due to any rounding errors. (1 / 180 is actually 0.00555555âŚ)
0 / 1 = 0, 1 / 0 = error. The advice to multiply is good though, division is more expensive than multiplication. Itâs a micro optimization though, so no need to change it if it isnât necessary.