Time.time returns the time which is timescale dependent. It does not increase while the editor is paused or looses focus.
So, wouldn’t it make sense that Time.unscaledTime operates the same, but disregards the time scale?
But it doesn’t. Time.unscaledTime keeps increasing even if the editor has been paused or lost focus.
It behaves more like Time.realtime since startup.
Isn’t the Unity Time API then not exposing a value which denotes some time that game has been playing, ignores timescale, and not counting time which no frames occurred (i.e. the editor was paused or didn’t update due to it loosing focus)?
Unless I’ve completely missed something in the Time API, I don’t anything there. So I’ve created this own code to accomplish the task.
public float lastFrameTime;
public float unscaledTimeWhilePlaying; //Keep a total of time, not scale dependent, while the playing and has focus (Updates are called)
public void Update()
{
float elapsedTimeThisFrame = Time.time - lastFrameTime; //Time scale dependent.
//Calculate the elapsed time. Do not consider timeScale.
//Do not consider time when not playing or editor does not have focus
elapsedTimeThisFrame = elapsedTimeThisFrame / Time.timeScale; //Disreagard timescale
unscaledTimeWhilePlaying += currentElapsedTime;
lastFrameTime = Time.time;
}
Am I missing something in the API or is something equivalent to the code above the only solution?
I believe Time.unscaledTime operates as intended, as it ignores the setting of Time.timeScale, and setting Time.timeScale to 0 is a typical way of pausing a game (when set to 0 no update or fixedupdate is run). It would be confusing if it treated pausing via setting timeScale and pausing via the editor button differently.
I don’t see a Time method though that does what you’re asking.
I vaguely remember unscaledTime working as you expect back in the day. But testing just now, yeah it appears to act as you describe.
Which is weird…
There doesn’t appear to be any meaningful difference between unscaledTime and realtimeSinceStartup as a result.
As for your code to accomplish your needs. You don’t have to do the division, you could just used unscaledDeltaTime and sum that up. I just tested, if you pause the game in editor, and then start again, the unscaledDeltaTime doesn’t last the duration of the pause, but is still a smaller relative value as one would expect.
Although I would say that due to the use of float addition, float error would begin to pile up, and your timer would start to drift. But this would only really make a difference if you comparing time and your tallied unscaledTime… and need to be deterministic to any degree.
There are events to work around this though:
OnApplicationPause:
OnApplicationFocus:
This way you don’t have to tally every Update. And instead just gather information at the events when the pause occurs.
FUNNY THING THOUGH.
OnApplicationPause doesn’t fire when you click the Pause button in the editor. But it does when it loses focus.
BUT
OnApplicationFocus fires for both the pause button and losing focus.
???
Should probably test that in runtime too. I’m on unity 5.6.3f1 right now.
All the tests I run, Time.unscaledTime is always the same value as Time.realtimeSinceStartup.
I am not getting the same results as you for some reason. I tested with Unity 5.3.6 and 2017.1.
Time.unscaledDeltaTime lasts as long as the time the game was not playing (paused or lost focus).
Run in the editor with this code. Then pause the editor. Then continue to hit the “Next frame” button.
Why is the same exact value continue to print out to the console every frame?
The only difference I see now of Time.unscaledTime and Time.realtimeSinceStartup is that Time.unscaledTime doesn’t increase while the pause button is activated. So if pausing the editor and hitting the “next frame” button shown above, Time.unscaledTime is the same value every frame, while Time.realtimeSinceStartup increases as expected.
I did a search through all of the Standard Assets code and all of the code of the assets I have, not once did anyone ever use Time.unscaledTime. Instead, Time.realtimeSinceStartup is used.
All I wanted was to get a time value while the editor is paused (to move items on a GUI), and handle cases when the editor lost focus or was paused.
This seems to do the trick:
float lastFrameRealtimeSinceStartup;
float unscaledTimeWhilePlaying;
void Update() {
float dRealtime = Time.realtimeSinceStartup - lastFrameRealtimeSinceStartup;
if (dRealtime > (1.0f / 20.0f)) {
//Assume the high dTime is due to the game being paused or lost focus
dRealtime = 1.0f / 20.0f; //Set it to a reasonable time (20 FPS)
}
unscaledTimeWhilePlaying += dRealtime;
lastFrameRealtimeSinceStartup = Time.realtimeSinceStartup;
}
It’s not mission critical, so this is good enough.