Search Unity

Question How can I calculate the race progress on a racetrack?

Discussion in 'Editor & General Support' started by LastFractal, Feb 28, 2024.

  1. LastFractal

    LastFractal

    Joined:
    Mar 6, 2022
    Posts:
    41
    I am working on a race progress tracking system. Currently I have a bunch of waypoints that covers the entire track, and each of them has a box trigger.

    Until now, what I was thinking of is: get the distance between the current waypoint and the next waypoint (using Vector3.distance), calculate the car's progress between the waypoints (basically the position of the X point on a AB vector), add the distance to the total travelled distance, and finally divide the total travelled distance by the total track length and multiply that by 100 to get the percentage.

    The orange text is the part that I'm stuck at. Not only that I have no idea how to implement it, but I am also not sure whether it's the best practice or not.
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,656
    Good start. That's the first step... that will get you which segment you're on.

    After that you can interpolate in various ways, what you put in orange above.

    Here's some notes to get you started:

    If you have two points, p1, p2, the distance is Vector3.Distance(p1,p2)

    That applies to find the gap between any two sequential waypoints.

    That also applies to find your distance from the waypoint you passed.

    It's common to keep an index as to which waypoint you crossed.

    And from that you can get the percent distance along the segment.

    And each waypoint would have an implicit percentage baked into it.

    Another way to find where you are on a segment is to use Vector3.InverseLerp() to get a value from 0 to 1 "alpha" which is "where am I between p1 and p2?"

    From the 0 to 1 "alpha" above, you can re-project with Vector3.Lerp() to know what the closest point along the given segment is to you.
     
  3. LastFractal

    LastFractal

    Joined:
    Mar 6, 2022
    Posts:
    41
    Well, I already have achieved that by dividing the current waypoint (which is changed when the car hits the trigger around the closest waypoint) by the amount of total waypoints and multiplying that by 100. Problem with this method is that, although being simple, you need a lot of waypoints (so triggers) to check the progress constantly, so the progress doesn't jump from 7% to 16%. This is not very practical and would as well impact the performance.

    The new method I was thinking of would solve all of my problems: the progress would be butter smooth while having less waypoints, so it's certainly a lot more practical.

    There is no InverseLerp function for Vector3 (which is not a problem since it's the same thing as Lerp(), just inversed). Problem here is, Vector3.Lerp() still lerps by a float (Vector3 a, Vector3 b, float t), and the car's transform is not a float; it's a Vector3.
     
  4. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,656
    Here's the first goog I found:

    Code (csharp):
    1. public static float InverseLerp(Vector3 a, Vector3 b, Vector3 value)
    2.     {
    3.         Vector3 AB = b - a;
    4.         Vector3 AV = value - a;
    5.         return Vector3.Dot(AV, AB) / Vector3.Dot(AB, AB);
    6.     }
    Correct.

    You're taking the cars position
    Feeding it into inverse lerp to get 0 to 1 between this waypoint and next waypoint
    using Vector.Lerp to produce new "on the line" position
    using distance to see how far along you are on that segment
    dividing to get your percentage.
     
  5. LastFractal

    LastFractal

    Joined:
    Mar 6, 2022
    Posts:
    41
    After a few days of trying, I finally got it to work. I still have minor imperfections such as the progress staying at 97% when the track is complete, and it sometimes reaching 100% few meters before the finish. I can't really assume what's the problem in here, which I currently don't want to bother with it anyways. It would be nice if I were able to solve this, but again, it being a few percent off doesn't really bother me.

    Thanks for the help!