Need help with multiple if statements.

So there are 2 variables, int Connections, and float Time, and a classification. Legendary, Epic, Excellent, and Good. I need to check to see which classification should be given. I am currently using if statements. I know there is a better way. If someone can see what my issue is, or a better way please let me know.

        //------------Detect What Classification Was Earned---------------
        //---References---
        GameObject levelIntro = GameObject.Find("Level Introduction");
        LevelIntroduction levelIntroScript = levelIntro.GetComponent<LevelIntroduction>();
        int curConnections = GameLogic.getTotalConnections();
        float curTime = GameLogic.getTotalTime();

        if ((curConnections >= levelIntroScript.LegendConnect 
            && curTime <= levelIntroScript.LegendTime) 
            && !(curTime >= levelIntroScript.EpicTime))
        {
            classification = "Legendary";
        }
        if((curConnections >= levelIntroScript.EpicConnect && curTime <= levelIntroScript.EpicTime)
            && !(curTime >= levelIntroScript.ExcellentTime))
        {
            classification = "Epic";
        }
        if ((curConnections >= levelIntroScript.ExcellentConnect && curTime <= levelIntroScript.ExcellentTime)
            && !(curTime >= levelIntroScript.GoodTime))
        {
            classification = "Excellent";
        }
        if (curConnections >= levelIntroScript.GoodConnect && curTime <= levelIntroScript.GoodConnect)
        {
            { classification = "Good"; }
        }
        //--------------------------------------------------------------------

Using else if statements after the first if, may improve your scripts performance. That way if one of the conditions is met, then the script will not check the rest of the else if statements after the one that was found to be true.

You have a minor error in the final if statement; you’re comparing Time to GoodConnect, which I presume should be GoodTime.

I have a couple of suggestions, though “better” in this case is really just going to be a matter of preference… everything is basically going to boil down to a bunch of ifs.

  1. You should use 'else if’s instead of the extra ‘&& !(time >= time)’. Presumably, if someone has a Legendary time, they do not also have an Epic time. Because you’re doing your comparisons from high to low, using else ifs will always get you the highest possible qualifying score category.

  2. Write a function to compare sets of scores.

    bool isBetterScore(int ScoreConnections, float ScoreTime, int ReferenceConnections, float ReferenceTime)
    {
    if (ScoreConnections >= ReferenceConnections && ScoreTime <= ReferenceTime)
    {
    return true;
    }
    return false;
    }

This looks better and is faster to write, but it’s a little hard to see what’s being compared, which leads us to…

  1. Combine the scores into a single object, say… CombinedScore:

    struct CombinedScore
    {
    int connections;
    float time;
    String scoreName;

    public CombinedScore(String name, int conns, float t)
    {
    scoreName = name;
    connections = conns;
    time = t;
    }
    }

    CombinedScore epicScore = new CombinedScore(“Epic”,
    levelIntroScript.EpicConnections,
    levelIntroScript.EpicTime);

With the first change (having a function), you can now change it to:

bool isBetterScore(CombinedScore playerScore, CombinedScore referenceScore)
..

.

This lets you hide most of the implementation details away in case you want to change them later. Don’t Repeat Yourself, if possible.

  1. Put the reference scores, in order, into a collection, then iterate (loop) over it:

    CombinedScore epicScore = …

    List referenceScoresFromHighToLow = new List()
    { legendaryScore, epicScore, excellentScore, goodScore }

    foreach (CombinedScore score in referenceScoresFromHighToLow)
    {
    if (isBetterScore(playerScore, score))
    {
    classification = score.scoreName;
    break;
    }
    }

Because this goes from High to Low, like your ifs, the loop will break out with the highest possible score that meets the requirements. You could also do this with a LINQ Find, which looks a little bit nicer but is a little bit less explicit.

First you would need to decide and explain to us how you want it to work. If “connections” is Legendary but “time” is Excellent, do we take the highest value (Legendary based on connections), the lowest (Excellent based on time) or perhaps Epic because that falls between your connection ranking and time ranking.

Without knowing the answer, something like this might simplify the problem for you (not the neatest solution but since you don’t want to use arrays etc…)

        int timeRank = 0;
		int connectionRank = 0;

		if (curConnections >= levelIntroScript.LegendConnect)
		{
			connectionRank = 4;
		} // use "else if" because if connections was Legendary, we don't even need to check if it was Epic
		else if (curConnections >= levelIntroScript.EpicConnect)
		{
			connectionRank = 3;
		}
		else if (curConnections >= levelIntroScript.ExcellentConnect)
		{
			connectionRank = 2;
		}    // if you're supposed to always get at least "Good" rank, there's no need to compare the score
		else // if (curConnections >= levelIntroScript.GoodConnect)
		{
			// everything less than the 3 top ranks gives a "good" rank
			connectionRank = 1;
		}

	    if (curTime <= levelIntroScript.LegendTime)
		{
			timeRank = 4;
		} // use "else if" because if curTime was Legendary, we don't even need to check if it was Epic
		else if (curTime <= levelIntroScript.EpicTime)
		{
			timeRank = 3;
		}
		else if (curTime <= levelIntroScript.ExcellentTime)
		{
			timeRank = 2;
		} // if you're supposed to always get at least "Good" time, there's no need to compare the time
		else // if (curTime <= levelIntroScript.GoodTime)
		{
			timeRank = 1;
		}

		// now you can check what ranks you got by evaluating the 2 numbers
		int maxRank = Mathf.Max(timeRank, connectionRank);
		int minRank = Mathf.Min(timeRank, connectionRank);
		int avgRank = (timeRank + connectionRank) / 2f;