Search Unity

unscaledTime vs. realtimeSinceStartup

Discussion in 'Scripting' started by Dracalis, May 27, 2018.

  1. Dracalis

    Dracalis

    Joined:
    Oct 11, 2014
    Posts:
    6
    Can someone explain the differences between Time.unscaledTime and Time.realtimeSinceStartup? From their descriptions in the documentation, they seem to do the same thing: tell you how much time has passed since the game started, independent of timeScale.

    When would you use one over the other? Is one more performant? Is one more accurate? Does one continue to count the time if tabbed out of the game and to a different application?

    Thanks.
     
    neonblitzer likes this.
  2. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    realtime since startup does say it counts time paused/in the background, and uses the system timer.
    Perhaps then unscaledTime does not.

    Run a quick test where you have 'run in background' disabled.. print out debug logs.. switch focus, and return and see what it says. :)?
     
  3. Dracalis

    Dracalis

    Joined:
    Oct 11, 2014
    Posts:
    6
    I ran the test, comparing both timers against Time.time. The two timers are nearly identical, down to the thousandth of a second, and will both run even when the game is paused in the background.

    When the application is paused:

    Time.time: Paused
    Time.unscaledTime: Running
    Time.realtimeSinceStartup: Running

    So that's one piece of the puzzle solved, but in addition to the questions above, that raises another one: is there a timer that's independent of timeScale but doesn't run while the application is paused?
     
  4. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    Interesting to learn, but sorry I don't have any answer beyond that. You could manually calculate the time the game was paused. :)
     
  5. Peter77

    Peter77

    QA Jesus

    Joined:
    Jun 12, 2013
    Posts:
    6,609
    Is Time.unscaleTime also advancing if you put the application in the background (think of a mobile app for example)?
     
  6. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    Yes, for me it appeared to be. I tested with 'run in background' disabled for windows, as well as on my phone (which is not my favourite thing to do lol).

    unscaledTime and realTime seemed to be the same up to 3 decimal places, let's say. ;)

    Perhaps I missed a setting or had to wait longer for background to kick in (no idea), but that's what I saw in a short test.
     
    Peter77 likes this.
  7. Dracalis

    Dracalis

    Joined:
    Oct 11, 2014
    Posts:
    6
    I've only tested it on Windows thus far, so I can't say if unscaledTime will keep counting on a mobile app yet.

    I just ran another test too. I changed the system time while the timers were running, and it didn't mess with their count. I'd initially suspected that it compared a system start time with the current system time, but even though I rolled the clock back, the values kept rising like nothing was altered.

    That's at least good to know for keeping count of the total game time, to help prevent easy cheating on speedrunning/time attack modes.
     
    Peter77 likes this.
  8. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,531
    unscaledTime:
    It's the amount of time that has passed since the start of the game at the beginning of this frame.

    Where as realTimeSinceStartup:
    So unravelling what this says, combined with evidence drawn by doing something like this:
    Code (csharp):
    1.  
    2.     IEnumerator Start()
    3.     {
    4.  
    5.         yield return new WaitForSeconds(1f);
    6.  
    7.         Debug.Log(Time.realtimeSinceStartup);
    8.         Debug.Log(Time.unscaledTime);
    9.  
    10.         System.Threading.Thread.Sleep(1000);
    11.  
    12.         Debug.Log(Time.realtimeSinceStartup);
    13.         Debug.Log(Time.unscaledTime);
    14.  
    15.     }
    16.  
    You can determine that realTimeSinceStartup is the time measured from the system clock at that very moment in time.

    It's not relative to the frame you're on, but relative to that exact moment that you call 'realTimeSinceStartup' based on the system clock.

    So in that example code I posted I ended up with:
    So, as you can tell, the 'unscaledTime' didn't change because the frame never advanced. Yet the realTimeSinceStartup did change, because we told the thread to wait 1 second.

    You'll also notice if we advance the frame again though:
    Code (csharp):
    1.  
    2.     IEnumerator Start()
    3.     {
    4.  
    5.         yield return new WaitForSeconds(1f);
    6.  
    7.         Debug.Log(Time.realtimeSinceStartup);
    8.         Debug.Log(Time.unscaledTime);
    9.  
    10.         System.Threading.Thread.Sleep(1000);
    11.  
    12.         Debug.Log(Time.realtimeSinceStartup);
    13.         Debug.Log(Time.unscaledTime);
    14.  
    15.         yield return new WaitForSeconds(1f);
    16.  
    17.         Debug.Log(Time.realtimeSinceStartup);
    18.         Debug.Log(Time.unscaledTime);
    19.  
    20.     }
    21.  
    I got:
    They came back into sync with one another because we're back at the beginning of a new frame. (if only off by a tiny amount of time because of the slight amount of time it took to call Debug.Log)
     
  9. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    Good point, and a nice addition. I didn't think of that kind of example.
     
  10. datagreed

    datagreed

    Joined:
    Sep 17, 2018
    Posts:
    42
    In my case unscaledTime bahaves in a very weird way:

    Code (CSharp):
    1. void Update()
    2.     {
    3.            
    4.             print($"realtimeSinceStartup time {Time.realtimeSinceStartup}; unscaledtime {Time.unscaledTime}; unscaled deltaTime {Time.unscaledDeltaTime}");
    5. }
    This give the following output on the two consequent frames:

    Code (CSharp):
    1. realtimeSinceStartup time 10.35588; unscaledtime 6.644372; unscaled deltaTime 0.02372694
    2. realtimeSinceStartup time 10.50492; unscaledtime 10.46146; unscaled deltaTime 3.817085
    How in the world unscaledtime jumped three seconds ahead of realtime?.. This thing seems very unreliable on 2018.2
     
  11. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,531
    Your unscaled didn't jump 3 seconds ahead of realtime. It just jumped 3.8 seconds (per the deltatime).

    Not sure why it jumped 3.8 seconds (unscaledTime isn't real time... it's game time). Not sure why your specific case had a 3.8 delta... but the fact that your time was about 3.8 seconds behind in (1), I'm wondering how it got behind that much. I suspect maybe you had a breakpoint somewhere? Or some code that blocked for a few seconds? Or did you by chance pause the editor?

    But, I feel I should repeat. unscaledTime and unscaledDeltaTime are related to 'game time'... this means it's simulated time. The engine may fluctuate from real time for various reasons since it's a simulation. This is why realtimesincestartup exists, to give you a real world (not governed by simulation) timer.
     
  12. datagreed

    datagreed

    Joined:
    Sep 17, 2018
    Posts:
    42
    I don't know, it just seems that the jump is present only in the several seconds after the scene is loaded. I didn;t find a solutions, so instead I had to rely on realtime.
     
  13. hk1ll3r

    hk1ll3r

    Joined:
    Sep 13, 2018
    Posts:
    88
    A 3 seconds gap makes sense if you didn't have any frames for that period. Maybe loading a heavy scene on a slow PC?