- Home /
How do I improve my racing game position calculations?
I am making some arcade kart racing game, and I developed a system to calculate the racer's positions on the track. How I did this is I made some checkpoint triggers which span the width of the whole track. During the race, I increment a value in the lapCounter script every time a player enters the trigger of the upcoming checkpoint. I also have another value in the lapCounter script which calculates the distance (float) from the player's own transform position to the next checkpoint position. So when the sort function sorts the list, it first compares two racers' current checkPointValue to determine who is past the other. If both of those are the same, then I compare the distance to the next checkpoint for both racers, and the one with less distance is past the other player since less distance means closer to next checkpoint. Now this works alright and all, but I have a wide section of the track, and I had to place the checkpoints in the middle. The problem occurs that even if I am past the other player according to the direction of the track, the other player will still have a higher position than me if he is near the middle of the track. We are on the same checkpoint, but the distance magnitude between the player and checkpoint is smaller for him than for me.
A diagram:
So I was wondering if there is another way to calculate the distance to the next checkpoint or calculate racer positions that would be more accurate. Thank you for anyone reading this to take their time out of their day!
Answer by StretchyPizza67 · Dec 09, 2020 at 06:56 PM
You can take all of the player positions and the goal position and project them onto the track direction vector.
Now our positions have been placed along the track direction vector, and our problem becomes 1D (along the track direction vector)
This can be done with Unity's Vector3.Project function.
Vector3 trackDirection = // .. value here
// for each player get their *projected* distance from goal
Vector3 playerToGoal = player.transform.position - goal.transform.position;
Vector3 projectedPlayerToGoal = Vector3.Project(playerToGoal, trackDirection);
float distance = projectedPlayerToGoal.magnitude;
This code can be run on all players, and then their distances can be compared. If you store positions as a Vector2, then you must convert them to a Vector3. Unity has no Vector2.Project function. You can convert the positions back to a Vector 2 when you are done, and the math will still work.
So one more thing to clarify, if the track direction constantly changes, do I use the direction vector from the previous and current checkpoint and set the difference of those two to the track direction? I have many placed around the track
Like this: Vector3 TrackDirection = currCheckpoint.position - prevCheckpoint.position;
To note, there's no absolute requirement to convert from a Vector2 to a Vector3 in that scenario. While the Vector3 struct includes a Project() function that Vector2 doesn't, that doesn't mean you can't just implement vector projection of your own:
public static Vector2 Project(Vector2 vector, Vector2 onNormal)
{
return onNormal * Vector2.Dot(vector, onNormal) / Vector2.Dot(onNormal, onNormal);
}
Answer by Konomira · Dec 09, 2020 at 12:37 PM
You could also check to see the distance from the previous checkpoint.
Yeah, I feel like your on to something, but I do not fully understand how this could improve it, could you please explain? Thanks.