Search Unity

Potential issue with Time.unscaledDeltaTime on 2018.2.20f1

Discussion in 'Scripting' started by claytoncurmi, Apr 24, 2019.

  1. claytoncurmi

    claytoncurmi

    Joined:
    Jul 6, 2010
    Posts:
    168
    Hi all,

    I am encountering an issue with the Time.unscaledDeltaTime not being properly set when the application is paused or out of focus. I am running the following script on Android device using builds from 2017.2.0f3 and 2018.2.20f1. This is the scenario I am trying;
    • Launch application
    • Once loaded, I lock the device
      • I start a timer (on another device) to keep track of how long the game has been actually suspended
    • I press the lock button on the device again and the application is resumed
      • Simultaneously I stop the timer
    • The first Update call that gets executed should report that the Time.unscaledDeltaTime since last frame
      • The expected result is that the Time.unscaledDeltaTime is equal to the time that the application has been paused (roughly the same to that reported by the timer)
      • What I actually get is a value less than expected, say if the game has been suspended for 40s the Time.unscaledDeltaTime is set to 16s.
    • This behaviour was noticed in 2018.2.20f1 but not reproducible on 2017.2.0f3 (works correctly here)
    Can someone verify or explain why this is happening?

    Code (CSharp):
    1. using System;
    2. using System.Text;
    3. using UnityEngine;
    4.  
    5. public class TimeDemo : MonoBehaviour
    6. {
    7.     private bool logNextDeltaTime;
    8.     private float lastUnscaledTime;
    9.     private StringBuilder logBuilder;
    10.  
    11.     private void Awake()
    12.     {
    13.         logBuilder = new StringBuilder();
    14.     }
    15.  
    16.     private void Update()
    17.     {
    18.         if (logNextDeltaTime)
    19.         {
    20.             var diff = Time.unscaledTime - lastUnscaledTime;
    21.             logBuilder.AppendLine(string.Format("Application is updating frame {0} with time {1} (+{2}s). Time difference should be +{3}s", Time.frameCount, Time.unscaledTime, Time.unscaledDeltaTime, diff));
    22.             logNextDeltaTime = false;
    23.         }
    24.     }
    25.  
    26.     private void OnApplicationFocus(bool focus)
    27.     {
    28.         logBuilder.AppendLine(string.Format("Application is focused - {0} in frame {1} with time {2}", focus, Time.frameCount, Time.unscaledTime));
    29.         if (!focus)
    30.         {
    31.             logBuilder.AppendLine(string.Format("Last unscaled time {0}", Time.unscaledTime));
    32.             lastUnscaledTime = Time.unscaledTime;
    33.             logNextDeltaTime = true;
    34.         }
    35.     }
    36.  
    37.     private void OnApplicationPause(bool pause)
    38.     {
    39.         logBuilder.AppendLine(string.Format("Application is paused - {0} in frame {1} with time {2}", pause, Time.frameCount, Time.unscaledTime));
    40.         if (pause)
    41.         {
    42.             logBuilder.AppendLine(string.Format("Last unscaled time {0}", Time.unscaledTime));
    43.             lastUnscaledTime = Time.unscaledTime;
    44.             logNextDeltaTime = true;
    45.         }
    46.     }
    47.  
    48.     private void OnGUI()
    49.     {
    50.         GUI.skin.GetStyle("label").fontSize = 35;
    51.         GUI.skin.GetStyle("button").fontSize = 35;
    52.  
    53.         if(GUILayout.Button("Clear Log", GUILayout.Width(300), GUILayout.Height(100)))
    54.         {
    55.             logBuilder = new StringBuilder();
    56.         }
    57.  
    58.         GUILayout.Label(logBuilder.ToString());
    59.     }
    60. }
     
  2. claytoncurmi

    claytoncurmi

    Joined:
    Jul 6, 2010
    Posts:
    168
    A weird fact that I noticed is that when the Android device is connected via USB with the machine, the unscaledDeltaTime values are correct. When it is disconnected, it doesn't work as expected. I updated the code to use the Android elapsedTime from its local clock and the values received are correct as seen in Unity 2017.2.0f3.

    Can someone confirm this issue?

    Code (CSharp):
    1. using System;
    2. using System.Text;
    3. using UnityEngine;
    4.  
    5. public class TimeDemo : MonoBehaviour
    6. {
    7.     private bool logNextDeltaTime;
    8.     private float prevTimestamp;
    9.     private StringBuilder logBuilder;
    10.  
    11.     private void Awake()
    12.     {
    13.         logBuilder = new StringBuilder();
    14.     }
    15.  
    16.     private void Update()
    17.     {
    18.         if (logNextDeltaTime)
    19.         {
    20.             #if UNITY_ANDROID && !UNITY_EDITOR
    21.             var currTimestamp = UnscaledTime();
    22.             #else
    23.             var currTimestamp = Time.unscaledTime;
    24.             #endif
    25.  
    26.             var diff = currTimestamp - prevTimestamp;
    27.             logBuilder.AppendLine(string.Format("Application is updating frame {0} with time {1} (+{2}s). Time difference should be +{3}s", Time.frameCount, Time.unscaledTime, Time.unscaledDeltaTime, diff));
    28.             logNextDeltaTime = false;
    29.         }
    30.     }
    31.  
    32.     private void OnApplicationFocus(bool focus)
    33.     {
    34.         logBuilder.AppendLine(string.Format("Application is focused - {0} in frame {1} with time {2}", focus, Time.frameCount, Time.unscaledTime));
    35.         if (!focus)
    36.         {
    37.             OnSuspended();
    38.         }
    39.     }
    40.  
    41.     private void OnApplicationPause(bool pause)
    42.     {
    43.         logBuilder.AppendLine(string.Format("Application is paused - {0} in frame {1} with time {2}", pause, Time.frameCount, Time.unscaledTime));
    44.         if (pause)
    45.         {
    46.             OnSuspended();
    47.         }
    48.     }
    49.  
    50.     private void OnGUI()
    51.     {
    52.         GUI.skin.GetStyle("label").fontSize = 35;
    53.         GUI.skin.GetStyle("button").fontSize = 35;
    54.  
    55.         if(GUILayout.Button("Clear Log", GUILayout.Width(300), GUILayout.Height(100)))
    56.         {
    57.             logBuilder = new StringBuilder();
    58.         }
    59.  
    60.         GUILayout.Label(logBuilder.ToString());
    61.     }
    62.  
    63.     private void OnSuspended()
    64.     {
    65.         #if UNITY_ANDROID && !UNITY_EDITOR
    66.         prevTimestamp = UnscaledTime();
    67.         #else
    68.         prevTimestamp = Time.unscaledTime;
    69.         #endif
    70.  
    71.         logNextDeltaTime = true;
    72.         logBuilder.AppendLine(string.Format("Last unscaled time {0}", prevTimestamp));
    73.     }
    74.  
    75.     private float UnscaledTime()
    76.     {
    77.         var systemClock = new AndroidJavaClass("android.os.SystemClock");
    78.         return systemClock.CallStatic<long>("elapsedRealtime") / 1000f;
    79.     }
    80. }