1

I have a day/night cycle in my game and I want a way for npc's to do certain things at certain times. In my day night cycle I have this code (I'm aware there's better ways to do what I'm trying to do, I just wanted to get it working for now)

        if (TimeOfDay >= 0 && TimeOfDay < 1) { Hours[0] = true; Hours[23] = false; }
    else if (TimeOfDay >= 1 && TimeOfDay < 2) { Hours[1] = true; Hours[0] = false; }
    else if (TimeOfDay >= 2 && TimeOfDay < 3) { Hours[2] = true; Hours[1] = false; }
    else if (TimeOfDay >= 3 && TimeOfDay < 4) { Hours[3] = true; Hours[2] = false; }
    else if (TimeOfDay >= 4 && TimeOfDay < 5) { Hours[4] = true; Hours[3] = false; }
    else if (TimeOfDay >= 5 && TimeOfDay < 6) { Hours[5] = true; Hours[4] = false; }
    else if (TimeOfDay >= 6 && TimeOfDay < 7) { Hours[6] = true; Hours[5] = false; }
    else if (TimeOfDay >= 7 && TimeOfDay < 8) { Hours[7] = true; Hours[6] = false; }
    else if (TimeOfDay >= 8 && TimeOfDay < 9) { Hours[8] = true; Hours[7] = false; }
    else if (TimeOfDay >= 9 && TimeOfDay < 10) { Hours[9] = true; Hours[8] = false; }
    else if (TimeOfDay >= 10 && TimeOfDay < 11) { Hours[10] = true; Hours[9] = false; }
    else if (TimeOfDay >= 11 && TimeOfDay < 12) { Hours[11] = true; Hours[10] = false; }
    else if (TimeOfDay >= 12 && TimeOfDay < 13) { Hours[12] = true; Hours[11] = false; }
    else if (TimeOfDay >= 13 && TimeOfDay < 14) { Hours[13] = true; Hours[12] = false; }
    else if (TimeOfDay >= 14 && TimeOfDay < 15) { Hours[14] = true; Hours[13] = false; }
    else if (TimeOfDay >= 15 && TimeOfDay < 16) { Hours[15] = true; Hours[14] = false; }
    else if (TimeOfDay >= 16 && TimeOfDay < 17) { Hours[16] = true; Hours[15] = false; }
    else if (TimeOfDay >= 17 && TimeOfDay < 18) { Hours[17] = true; Hours[16] = false; }
    else if (TimeOfDay >= 18 && TimeOfDay < 19) { Hours[18] = true; Hours[17] = false; }
    else if (TimeOfDay >= 19 && TimeOfDay < 20) { Hours[19] = true; Hours[18] = false; }
    else if (TimeOfDay >= 20 && TimeOfDay < 21) { Hours[20] = true; Hours[19] = false; }
    else if (TimeOfDay >= 21 && TimeOfDay < 22) { Hours[21] = true; Hours[20] = false; }
    else if (TimeOfDay >= 22 && TimeOfDay < 23) { Hours[22] = true; Hours[21] = false; }
    else if (TimeOfDay >= 23 && TimeOfDay < 24) { Hours[23] = true; Hours[22] = false; }

Explain the code - TimeOfDay is a float from 0-24 the resets to 0 when it hits 24. The Hours array is an array of bools with size 24. What the code does is each new hour, it turns on which hour it is, and then turns off the old hour.

This is running in the update() function of unity so its constantly running. Take for example its in this if statement TimeOfDay >= 0 && TimeOfDay < 1 Because of that every frame its doing Hours[0] = true; Hours[23] = false;. Is that safe to do? I feel like constantly setting bools to its value is not efficient. I don't think I feel any lag changes but I'm not sure. Is there anyway to optimize/fix this? Or is this okay for unity?

Matthew Z
  • 47
  • 4
  • Maybe if you explain what this code does we could help to simplify it. That's a mess. It may not cause you any issues but it's ugly and hard to maintain. – Retired Ninja Jul 09 '23 at 05:20
  • @RetiredNinja sorry, I edited it, I hope that helps. – Matthew Z Jul 09 '23 at 05:26
  • How do you use the array? What would happen if two value were set to true because the logic to set the last one to false isn't necessarily foolproof> – Retired Ninja Jul 09 '23 at 05:31
  • @RetiredNinja TimeOfDay will always go up and never backwards. At least from testing I haven't had a moment where two of the hours were true at the same time. – Matthew Z Jul 09 '23 at 05:33
  • `Hours[(int)TimeOfDay] = true;` could replace almost all of that code other than setting the other indices to false which you could use a loop for before you set one to true. Still unsure what the array is actually for. I'd guess you probably don't need that either, just the integer hour value. – Retired Ninja Jul 09 '23 at 06:00
  • @RetiredNinja basically I want to be able to fully customize a npcs schedule. So if I want them to sleep for 19 hours of the day I could. In the a npc script I check what hour it is and change what they need to do accordingly. If it was an int instead of bools, wouldn’t I still need something like “if(hour==1) changeSchedule” and so on for all hours? – Matthew Z Jul 09 '23 at 06:06
  • You realize you can use relational operators ( < <= > >= ) with numerical values? Using a `bool[]` looks really awkward. – Fildor Jul 09 '23 at 06:19
  • I'd also recommend to use something like `TimeSpan` or `TimeOnly` if available in Unity. – Fildor Jul 09 '23 at 06:21

2 Answers2

1

There is nothing particularly wrong with setting bools and variables repeatedly. CPUs are very efficient at comparing integers and setting memory locations.

If you are extremely nitpicky, you could rewrite the code to avoid any conditions, which allows the CPU to use better branch prediction and a more efficient pipeline. It's counterintuitive but this might actually be more efficient:

Hours[0] = (TimeOfDay >= 0 && TimeOfDay < 1);
Hours[1] = (TimeOfDay >= 1 && TimeOfDay < 2);
Hours[2] = (TimeOfDay >= 2 && TimeOfDay < 3);

While there's a chance that the additional memory writes could make it slower, all the elements in the Hours array are likely to be in the same cache line so I doubt it.

And of course you realize you could do this all in a loop, or just declare Hours as a property:

public bool IsHour(int hourNumber) => TimeOfDay > hourNumber && TimeOfDay < hourNumber + 1;

I would not spend too much time worrying about any of this though.

John Wu
  • 50,556
  • 8
  • 44
  • 80
0

I'm too lazy to write all those if statements. Add a new 'currentHour' variable to track what you last did and just set that to false before setting the TimeOfDay again (open dotnetfiddle web site and drop this in):

public class Program
{
    static int currentHour = 0;
    static float TimeOfDay;
    static bool[] Hours = new bool[24];
    public static void Main()
    {
        TimeOfDay = 0.91f;
        Update();

        TimeOfDay = 1.01f;
        Update();

        TimeOfDay = 23.99f;
        Update();
    }

    private static void Update()
    {
        Hours[currentHour] = false;
        //Console.WriteLine("Hour: " + currentHour + ", " + Hours[currentHour]);
        currentHour = (int)TimeOfDay;
        Hours[currentHour] = true;
        //Console.WriteLine("Hour: " + currentHour + ", " + Hours[currentHour]);
    }
}
Dustin_00
  • 345
  • 2
  • 8