Logic on calculating positions in a race.

I’m doing a race game, and trying to calcualte the order the players are.
I have a list of cars, and three int arrays indicating in witch lap, checkpoint and position. (The current lap of the car in carList[0] is currentLap[0]).

I read that i have to compare by lap, if there are 2 cars in the same lap, compare by checkpoint and if there are 2 cars in the same lap and checkpoint compare by distance to the next checkpoint. The problem is I have no idea how to code it.

using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class RaceManager : MonoBehaviour {
	
	public Waypoint startWaypoint;
	public List<Waypoint> waypointsList;
	public List<Car> carList;	
	public int[] currentLap;
	public int[] currentWaypoint;
	public int[] positions;
	
	
	
	// Use this for initialization
	public void Initialize() {
		currentWaypoint = new int [carList.Count];
		currentLap = new int [carList.Count];
		positions = new int [carList.Count];
		
		waypointsList.Clear();
		Waypoint tempWaypoint;
		waypointsList.Add(startWaypoint);
		tempWaypoint = startWaypoint;
		while(tempWaypoint.nextWaypoint != startWaypoint){
			if(tempWaypoint.nextWaypoint == null){
				Debug.LogError("Next waypoint is null");
			}
			waypointsList.Add(tempWaypoint.nextWaypoint);
			tempWaypoint = tempWaypoint.nextWaypoint;
		}
		
		for (int i = 0; i < waypointsList.Count; i++) {
			waypointsList*.raceManager = this;*
  •  }*
    
  •  AssignIDToWaypoints();*
    
  • }*

  • public void PassedThroughWaypoint(int carID, int waypointID){*

  •  //cars ID start at 1.*
    
  •  if(currentWaypoint[carID-1] == waypointID - 1){*
    
  •  	currentWaypoint[carID-1]++;*
    
  •  }else{*
    
  •  	if(currentWaypoint[carID-1] == waypointsList.Count - 1 && waypointID == 0){*
    
  •  		currentWaypoint[carID-1] = 0;*
    
  •  		currentLap[carID-1]++;*
    
  •  	}*
    
  •  }*
    
  • }*

  • private void AssignIDToWaypoints(){*

  •  for (int i = 0; i < waypointsList.Count; i++) {*
    

_ waypointsList*.waypointID = i;_
_
}_
_
}*_

* private void CalculatePositions(){*
* //Here is where I need help.*
* }*

}

Use this code. Each waypoint must have a trigger collider, and must be tagged “1”, “2”, “3”… according to the number of the waypoint.

Each Car object should be assigned with the Car script.

The RaceManager should be assigned with the race manager script, and you need to drag & drop each Car gameobject to the carObjects variable in the script, so it has a reference to all cars.

What this does, is keep for each car the current waypoint, lap and the transform of the last waypoint. Then each car can calculate the distance traveled. Then each car can calculate it’s position in the race, by comparing to all other cars. The race manager then keeps an array of carOrder, which has all the cars in the correct order.

using UnityEngine;
using System.Collections;

public class Car : MonoBehaviour {
    public int currentWaypoint;
    public int currentLap;
    public Transform lastWaypoint;

    private static int WAYPOINT_VALUE = 100;
    private static int LAP_VALUE = 10000;

    // Use this for initialization
    public void Initialize() {
        currentWaypoint = 0;
        currentLap = 0;
    }

    public void OnTriggerEnter(Collider other) {
        string otherTag = other.gameObject.tag;
        currentWaypoint = System.Convert.ToInt32(otherTag);
        if (currentWaypoint == 1) // completed a lap, so increase currentLap;
            currentLap++;
        lastWaypoint = other.transform;
    }

    public float GetDistance() {
        return (transform.position - lastWaypoint.position).magnitude + currentWaypoint * WAYPOINT_VALUE + currentLap * LAP_VALUE;
    }

    public int GetCarPosition(Car[] allCars) {
        float distance = GetDistance();
        int position = 1;
        foreach (Car car in allCars) {
            if (car.GetDistance() > distance)
                position++;
        }
        return position;
    }
}
public class RaceManager : MonoBehaviour {
    public GameObject[] carObjects;
    public Car[] allCars;
    public Car[] carOrder;

    public void Start() {
        // set up the car objects
		allCars = new Car[carObjects.Length];
        carOrder = new Car[carObjects.Length];
		for (int i = 0; i < carObjects.Length; i++) {
		    allCars _= carObjects*.GetComponent<Car>();*_

* }*
}

// this gets called every frame
public void update() {
foreach (Car car in allCars) {
carOrder[car.GetCarPosition(allCars) - 1] = car;
}
}
}

This is my code for car positioning in a race.

using UnityEngine;
using System.Collections;

public class RaceManager : MonoBehaviour {

	int Racer1Laps;
	int Racer1CurrentCheckpoint;
	
	int Racer2Laps;
	int Racer2CurrentCheckpoint;
	
	int GetPosition(){
		int Position = 1;
		
		if(Racer1Laps < Racer2Laps){
			Position++;
		}

		if(Racer1Laps == Racer2Laps){
			if(Racer1CurrentCheckpoint < Racer2CurrentCheckpoint){
				Position++;
			}
		}

		if(Racer1CurrentCheckpoint == Racer2CurrentCheckpoint && Racer1Laps == Racer2Laps){
			if(Vector3.Distance(Racer1.position, Racer1CurrentCheckpoint.position) > Vector3.Distance(Racer2.position, Racer2CurrentCheckpoint.position)){
				Position++;
			}
		}
		
		return Position;
	}
}

Here’s a new version of Tomer Barkan’ scripts with a couple of improvements.

  1. The old Car script didn’t filter wrong direction and multiple laps increase.
  2. The RaceManager script has one too many array to store the car references, so i removed carObject!

Each waypoint must have a trigger collider, and must be tagged “1”, “2”, “3”… according to the number of the waypoint.

Each Car object should be assigned with the Car script.

You have to manually set the total number of Waypoints to the nbWaypoint variable and it’s preferable that you set lastWaypoint variable to the last waypoint before beginning, so the script would work before the first lap and without console’s errors.

The RaceManager should be assigned with the race manager script, and you need to drag & drop each Car gameobject to the allCars variable in the script, so it has a reference to all cars’ script.

The Script “Car.cs”:

using UnityEngine;
using System.Collections;

public class Car : MonoBehaviour {
	public int currentWaypoint;
	public int currentLap;
	public Transform lastWaypoint;
	public int nbWaypoint; //Set the amount of Waypoints

	private static int WAYPOINT_VALUE = 100;
	private static int LAP_VALUE = 10000;
	private int cpt_waypoint = 0;

	// Use this for initialization
	public void Initialize() {
		currentWaypoint = 0;
		currentLap = 0;
		cpt_waypoint = 0;
	}

	public void OnTriggerEnter(Collider other) {
		string otherTag = other.gameObject.tag;
		currentWaypoint = System.Convert.ToInt32(otherTag);
		if (currentWaypoint == 1 && cpt_waypoint == nbWaypoint) { // completed a lap, so increase currentLap;
			currentLap++;
			cpt_waypoint = 0;
		}
		if (cpt_waypoint == currentWaypoint - 1) {
			lastWaypoint = other.transform;
			cpt_waypoint++;
		}
	}

	public float GetDistance() {
		return (transform.position - lastWaypoint.position).magnitude + currentWaypoint * WAYPOINT_VALUE + currentLap * LAP_VALUE;
	}

	public int GetCarPosition(Car[] allCars) {
		float distance = GetDistance();
		int position = 1;
		foreach (Car car in allCars) {
			if (car.GetDistance() > distance)
				position++;
		}
		return position;
	}
}

The Script “RaceManager.cs”:

using UnityEngine;
using System.Collections;

public class RaceManager : MonoBehaviour {
	public Car[] allCars;
	public Car[] carOrder;

	public void Start() {
		// set up the car objects
		carOrder = new Car[allCars.Length];
		InvokeRepeating ("ManualUpdate", 0.5f, 0.5f);
	}

	// this gets called every frame
	public void ManualUpdate() {
		foreach (Car car in allCars) {
			carOrder[car.GetCarPosition(allCars) - 1] = car;
		}
	}
}

Is my mistake in this?

FormatException: Input string was not in the correct format
System.Int32.Parse (System.String s) (at /Users/builduser/buildslave/mono/build/mcs/class/corlib/System/Int32.cs:629)
System.Convert.ToInt32 (System.String value) (at /Users/builduser/buildslave/mono/build/mcs/class/corlib/System/Convert.cs:1270)
Car.OnTriggerEnter (UnityEngine.Collider other) (at Assets/Scripts/Car.cs:25)

FormatException: Input string was not in the correct format
System.Int32.Parse (System.String s) (at /Users/builduser/buildslave/mono/build/mcs/class/corlib/System/Int32.cs:629)
System.Convert.ToInt32 (System.String value) (at /Users/builduser/buildslave/mono/build/mcs/class/corlib/System/Convert.cs:1270)
Car.OnTriggerEnter (UnityEngine.Collider other) (at Assets/Car.cs:25)
PLZ HELP

if (other.tag == “CheckPoint”)

{

currentWaypoint = int.Parse (other.name);

Debug.Log (this.gameObject.name + "-check: " + currentWaypoint);

if (currentWaypoint == 1 && cpt_waypoint == nbWaypoint)

{ // completed a lap, so increase currentLap;

currentLap++;

cpt_waypoint = 0;

}

if (cpt_waypoint == currentWaypoint - 1)

{

lastWaypoint = other.transform;

cpt_waypoint++;

}

}

Instead of giving tag to Waypoints name them “1”,“2”,… and tag all waypoints… I tagged them ‘CheckPoint’.

Hi,

any update with working code?

++