Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Have a look at our Games Focus blog post series which will show what Unity is doing for all game developers – now, next year, and in the future.
    Dismiss Notice

Question Bloated Timer

Discussion in 'Editor & General Support' started by Lophane, Nov 25, 2022 at 5:07 AM.

  1. Lophane

    Lophane

    Joined:
    Nov 15, 2022
    Posts:
    6
    Hey there, to preface my question and code I just started learning Unity and C# a bit over a week ago.

    So I started with following a tutorial bit I finished that a few days ago and have since been editing and adding in things that I want to try out, I'm sure I'm not doing everything super well and it wouldn't be scalable but I know what's going on and it works as I try to make bigger projects I'm sure I'll progress with a few (many) growing pains.
    My most recent addition has been a timer for the level, every second that passes deducts points from the player's total which is all good, easy enough to just get the 'Time.timeSinceLevelLoad' and just do a bit of math with it to get it to the right number*.
    However, when trying to get the timer up on the UI I have encountered... well not a problem, It's working fine, but it feels like some major bloat and I'm hopeful that It's just because of my inexperience and lack of knowledge of the vocabulary of C#, here it is:

    Code (CSharp):
    1.  
    2. void Update()
    3.     {
    4.  
    5.         //This displays the current time since the level was loaded as long as the level is still running
    6.         if (gameHasEnded == false && Victory == false)
    7.         {
    8.             if ((Mathf.Ceil((Time.timeSinceLevelLoad) - 1f)) < 10f)
    9.             {
    10.                 timeTaken = (Mathf.Ceil((Time.timeSinceLevelLoad) - 1f)).ToString("0");
    11.                 TimerText.SetText("Time: 00:0" + timeTaken);
    12.             }
    13.             else if ((Mathf.Ceil((Time.timeSinceLevelLoad) - 1f)) < 60f)
    14.             {
    15.                 timeTaken = (Mathf.Ceil((Time.timeSinceLevelLoad) - 1f)).ToString("0");
    16.                 TimerText.SetText("Time: 00:" + timeTaken);
    17.             }
    18.             else if ((Mathf.Ceil((Time.timeSinceLevelLoad) - 1f)) >= 60f && ((Mathf.Ceil((Time.timeSinceLevelLoad) - 1f)) % 60f) < 10f)
    19.             {
    20.                 TimerText.SetText("Time: 0" + (Mathf.Floor((Mathf.Ceil((Time.timeSinceLevelLoad) - 1f)) / 60f)) + ":0" + ((Mathf.Ceil((Time.timeSinceLevelLoad) - 1f)) % 60f));
    21.             }
    22.             else if ((Mathf.Ceil((Time.timeSinceLevelLoad) - 1f)) >= 60f && ((Mathf.Ceil((Time.timeSinceLevelLoad) - 1f)) % 60f) < 60f)
    23.             {
    24.                 TimerText.SetText("Time: 0" + (Mathf.Floor((Mathf.Ceil((Time.timeSinceLevelLoad) - 1f)) / 60f)) + ":" + ((Mathf.Ceil((Time.timeSinceLevelLoad) - 1f)) % 60f));
    25.             }
    26.             else if ((Mathf.Ceil((Time.timeSinceLevelLoad) - 1f)) >= 600f && ((Mathf.Ceil((Time.timeSinceLevelLoad) - 1f)) % 60f) < 60f)
    27.             {
    28.                 TimerText.SetText("Time: " + (Mathf.Floor((Mathf.Ceil((Time.timeSinceLevelLoad) - 1f)) / 60f)) + ":" + ((Mathf.Ceil((Time.timeSinceLevelLoad) - 1f)) % 60f));
    29.             }
    30.             else if ((Mathf.Ceil((Time.timeSinceLevelLoad) - 1f)) >= 6000f &&  ((Mathf.Ceil((Time.timeSinceLevelLoad) - 1f)) % 60f) < 60f)
    31.             {
    32.                 TimerText.SetText("Time: Oh hell naw");
    33.             }
    34.         }
    35.  
    36.        //This will lock the display timer at the instant that either Defeat or Victory is declared true
    37.         else if (Defeat == true | Victory == true)
    38.         {
    39.             if ((Mathf.Ceil((Time.timeSinceLevelLoad) - 1f)) < 10f)
    40.             {
    41.                 TimerText.SetText("Time: 00:0" + timeTaken);
    42.             }
    43.             else if ((Mathf.Ceil((Time.timeSinceLevelLoad) - 1f)) < 60f)
    44.             {
    45.                 TimerText.SetText("Time: 00:" + timeTaken);
    46.             }
    47.             else if ((Mathf.Ceil((Time.timeSinceLevelLoad) - 1f)) >= 60f)
    48.             {
    49.                 TimerText.SetText("Time: " + timeTaken + " seconds");
    50.             }
    51.         }
    52.     }
    53.  

    (The levels usually only take 20-40 seconds apiece)
    Yea, I mean maybe this is fine but compared to everything else I've been writing this is a ton of if's, if else's, and it's all checked every frame as it is in 'void Update()'.
    Is there an easier way to display a 00:00 timer without having a new if (else) statement for each new digit of the timer?
    Any help is appreciated, thanks!

    *Side note: I am having a few issues with multiple scripts referencing back to the UI, is it better to have a script for each variable part of the UI or is there a way to have the UI covered by 1 script, it always gives me an error if I try to do more than 1 text box
     
  2. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    2,795
    You can use the C# TimeSpan struct to easily generate formatted time strings: https://learn.microsoft.com/en-us/dotnet/api/system.timespan.tostring?view=net-7.0

    I would just keep track of a float value and tick it up with
    Time.deltaTime
    each frame:
    Code (CSharp):
    1. public float LevelTime;
    2.  
    3. private void Update()
    4. {
    5.     LevelTime += Time.deltaTime;
    6.    
    7.     string timeString = TimeSpan.FromSeconds(LevelTime).ToString("mm:ss");
    8.    
    9.     TimerText.SetText(timeString);
    10. }
    The format string in
    .ToString()
    may be wrong. I always forget the right way to do it.
     
  3. Lophane

    Lophane

    Joined:
    Nov 15, 2022
    Posts:
    6

    Thanks a ton, there was a bit of adjusting to do but I got that figured out no problem this was the final working code:


    Code (CSharp):
    1.  
    2. public float LevelTime;
    3.  
    4. private void Update()
    5. {
    6.     LevelTime += Time.deltaTime;
    7.  
    8.     string timeString = (LevelTime).ToString("00:00");
    9.  
    10.     timerText.SetText(timeString);
    11. }
    12.  
    Thanks again!
     
    spiney199 likes this.
unityunity