How to use IComparer to compare more than one value when array sorting.

Hi guys. Basically, I need help with a ranking system I am building. At the moment, I have basic waypoint ranking working. however, to make it more accurate, I wish to also count laps and the distance to the next waypoint also when doing the ordering. How would I go about doing this?

BTW, here’s the plugin (aka. my script) I use for ranking:

#pragma strict
import System;

var countdown : int;
static var start : boolean = false;
static var laps : int;
var noOfLaps : int;
var cars : GameObject[];
var update : boolean = true;
var timer1 : int = 0;
var timer2 : int = 0;
var PlayerCar : GameObject;

function Start () {
    laps = noOfLaps;
    cars = GameObject.FindGameObjectsWithTag("Car");
 
    //run timers.
    while (true) {
        countdown -= 1;
        timer1++;
        if (timer1 > 1){
            update = true;
        }
        if (countdown <= 1){
            start = true;
        }
        yield WaitForSeconds(1);
    }
}

function Update () {
    if (update) {
        cars.Sort(cars, new UpdateRanks_Laps());
        update = false;
    }
}

function OnGUI () {
    if (countdown > 1){
        var temp = countdown - 1;
        GUI.Box(Rect(Screen.width/2-128, Screen.height/2-128, 256, 256), temp.ToString());
    }
    if (countdown < 2 && countdown > 0) {
        GUI.Box(Rect(Screen.width/2-128, Screen.height/2-128, 256, 256), "GO!");
    }
    var playerRank = System.Array.IndexOf(cars, PlayerCar)+1;
    GUI.Box (Rect(0,0, 150, 150), playerRank.ToString());
}

class UpdateRanks_Laps implements IComparer
{
    function Compare(a : System.Object, b : System.Object) : int
    {
        if ( !(a instanceof GameObject) || !(b instanceof GameObject)) return;
        var CarA : GameObject = a;
        var CarB : GameObject = b;
        return CarB.GetComponent(Rank_Sys).currentWaypoint.CompareTo(CarA.GetComponent(Rank_Sys).currentWaypoint);
    }
}

the only problem is in the class itself, I need some way of comparing more values than just one. :wink:

Hi, not to worry, I figured it out! :slight_smile:

class UpdateRanks_Laps implements IComparer
{
    function Compare(a : System.Object, b : System.Object) : int {
        if ( !(a instanceof GameObject) || !(b instanceof GameObject)) return;
        var CarA : GameObject = a;
        var CarB : GameObject = b;
       
        if (CarB.GetComponent(Rank_Sys).lap.CompareTo(CarA.GetComponent(Rank_Sys).lap)){
            return CarB.GetComponent(Rank_Sys).lap.CompareTo(CarA.GetComponent(Rank_Sys).lap);
        }
        if (CarB.GetComponent(Rank_Sys).currentWaypoint.CompareTo(CarA.GetComponent(Rank_Sys).currentWaypoint)){
            return CarB.GetComponent(Rank_Sys).currentWaypoint.CompareTo(CarA.GetComponent(Rank_Sys).currentWaypoint);
        }
        else {
            return CarA.GetComponent(Rank_Sys).dist.CompareTo(CarB.GetComponent(Rank_Sys).dist);
        }
    }
}

In other words, I do a sequenced check. (Is that the right word? :smile:) First, check lap: failing that, check waypoint: Failing that, check distance: the distance usually isn’t the same, as I use floats for distance calculation. equals: FLAWLESS RAKINGS!

For anyone trying to do the same, feel free to use this code, it is officially public domain! :slight_smile: