3/4 Player positioning not working.

Hey all currently working on a racing game and 2 player positioning works perfectly but 3 to 4 player positioning is a little broken. Now i know the code i made is terrible and I know the issue which is that when it gets to the lapnumber check and starts checking checkpoints it doesn’t take into account if a kart is a lap ahead or a checkpoint ahead is there away i can edit what I have to accomodate it because the only fix i can think of involves another like 150 if statements to check every possible outcome which is just… no, is there a better way to go about doing it? Kartlapcheck and kartcheckpointcheck just compares the 3 karts values and returns true if the first kart is higher than the other two.
Any help would be great!

  void positionCalculator(PlayerActor kart, GameObject go_kart, PlayerActor karttwo, GameObject go_karttwo,
                            PlayerActor kartthree, GameObject go_kartthree)
    {
        //Kart One
        if (kartLapCheck(kart, karttwo, kartthree))
        {
            kart.kartPosition = 1;
            karttwo.kartPosition = 2;
            kartthree.kartPosition = 3;
        }
        else if (kartLapCheck(kart, kartthree, karttwo))
        {
            kart.kartPosition = 1;
            kartthree.kartPosition = 2;
            karttwo.kartPosition = 3;
        }
        //Kart Two.
        else if (kartLapCheck(karttwo, kart, kartthree))
        {
            karttwo.kartPosition = 1;
            kart.kartPosition = 2;
            kartthree.kartPosition = 3;
        }
        else if (kartLapCheck(karttwo, kartthree, kart))
        {
            karttwo.kartPosition = 1;
            kartthree.kartPosition = 2;
            kart.kartPosition = 3;
        }
        //kart three
        else if (kartLapCheck(kartthree, kart, karttwo))
        {
            kartthree.kartPosition = 1;
            kart.kartPosition = 2;
            karttwo.kartPosition = 3;
        }
        else if (kartLapCheck(kartthree, karttwo, kart))
        {
            kartthree.kartPosition = 1;
            karttwo.kartPosition = 2;
            kart.kartPosition = 3;
        }
        else if ((kart.lapNumber == karttwo.lapNumber) && (kart.lapNumber == kartthree.lapNumber) && (karttwo.lapNumber == kartthree.lapNumber))
        {
            if(kartCheckpointCheck(kart, karttwo, kartthree))
            {
                kart.kartPosition = 1;
                karttwo.kartPosition = 2;
                kartthree.kartPosition = 3;
            }
            else if(kartCheckpointCheck(kart, kartthree, karttwo))
            {
                kart.kartPosition = 1;
                kartthree.kartPosition = 2;
                karttwo.kartPosition = 3;
            }
            else if(kartCheckpointCheck(karttwo, kart, kartthree))
            {
                karttwo.kartPosition = 1;
                kart.kartPosition = 2;
                kartthree.kartPosition = 3;
            }
            else if(kartCheckpointCheck(karttwo, kartthree, kart))
            {
                karttwo.kartPosition = 1;
                kartthree.kartPosition = 2;
                kart.kartPosition = 3;
            }
            else if(kartCheckpointCheck(kartthree, kart, karttwo))
            {
                kartthree.kartPosition = 1;
                kart.kartPosition = 2;
                karttwo.kartPosition = 3;
            }
            else if(kartCheckpointCheck(kartthree, karttwo, kart))
            {
                kartthree.kartPosition = 1;
                karttwo.kartPosition = 2;
                kart.kartPosition = 3;
            }
            else if ((kart.checkPointCounter == karttwo.checkPointCounter) && (karttwo.checkPointCounter == kartthree.checkPointCounter))
            {
                float dist1 = Vector3.Distance(go_kart.transform.position, kart.nextCheckPoint.transform.position);
                float dist2 = Vector3.Distance(go_karttwo.transform.position, karttwo.nextCheckPoint.transform.position);
                float dist3 = Vector3.Distance(go_kartthree.transform.position, kartthree.nextCheckPoint.transform.position);

                if ((dist1 < dist2) && (dist2 < dist3))
                {
                    kart.kartPosition = 1;
                    karttwo.kartPosition = 2;
                    kartthree.kartPosition = 3;
                }
                else if ((dist1 < dist3) && (dist3 < dist2))
                {
                    kart.kartPosition = 1;
                    karttwo.kartPosition = 3;
                    kartthree.kartPosition = 2;
                }
                else if ((dist2 < dist1) && (dist1 < dist3))
                {
                    kart.kartPosition = 2;
                    karttwo.kartPosition = 1;
                    kartthree.kartPosition = 3;
                }
                else if ((dist2 < dist3) && (dist3 < dist1))
                {
                    kart.kartPosition = 3;
                    karttwo.kartPosition = 1;
                    kartthree.kartPosition = 2;
                }
                else if ((dist3 < dist1) && (dist1 < dist2))
                {
                    kart.kartPosition = 2;
                    karttwo.kartPosition = 3;
                    kartthree.kartPosition = 1;
                }
                else if ((dist3 < dist2) && (dist2 < dist1))
                {
                    kart.kartPosition = 3;
                    karttwo.kartPosition = 2;
                    kartthree.kartPosition = 1;
                }
            }
        }

is there a better way to go about doing it?

Yes. There is always a better way than lots of if statements. Also, having variable names that are basically the same except for a number (“kart1, kart2, kart3”) is just as avoidable.

Your friend in this case: Collections and Arrays. First off, instead of multiple variables, each for one kart, make one variable that references an array of karts:

GoKart kart1;
GoKart kart2;
GoKart kart3;
// becomes
GoKart[] karts;

You can access the karts using array indexing:

karts[0] // first kart
karts[1] // second kart
// and so on

This allows you to pass an arbitrary number of karts rather than having afunction that can only work with exactly X karts.

Now, for sorting these karts. There’s multiple ways of solving this. I’ll just propose a simple Linq statement, which is pretty short and nice, but I don’t claim that this is the best or most efficient way or whatever.

First, put your karts into a List:

var kartList = new List<GoKart>(karts);

You can instead use a list instead of an array from the start. The main difference between arrays and lists is that arrays cannot grow or shrink, while lists can get more elements or remove them. In this case, we use a list for the Linq statement.

At the top of your script, at the using statements, you need

using System.Linq;

and then you can do this with your list:

kartList.OrderBy(kart => kart.lapNumber).ThenBy(kart => kart.checkpointNumber).ThenBy(kart => kart.DistanceToNextCheckpoint());

You will then have your karts ordered by race progress in that list, “kartList[0]” being the kart in the pole position.

I have replaced the Vector3.Distance call with a Call to DistanceToNextCheckpoint for the sake of loose coupling. Implement this method in the GoKart class with the Vector3.Distance call you already have.

As mentioned, there are other ways to do this. The Linq statement is pretty short and sexy, but you might have a better idea about what happens if you implement the sorting by yourself. Consider looking up arrays and lists for further informations either way.