- Home /
Time.timeScale seems doesn't work with Update
Hi
I don't manage to pause my game with Time.timeScale and function update(). Actually my script works very well when i used FixedUpdate(). But when i use in script "function Update()" my script doesn't pause.
I print Time.timeScale during update and i see that the value change to 0 when i push pause button.
Is it possible that because i use in first scene this linecode: Application.targetFrameRate = 30;
This is what i have in ProjectSettings/Time Fixed timestep: 0.03333333 Maximun allowed time : 1 TimeScale : 1
What i'm doing wrong? Can i use timeScale with Update script?
Thanks!! Baptiste
This might help. What isn't behaving like it should in your game ?
baptiste : Thank you Berenger I saw that thread. And that i understand, it's that i can use Time.timescale = 0 to pause every linecode in one update function. Right?
$$anonymous$$y problem is, Update function is still calling even when my timScale is 0.
And that i understand, it's that i can use Time.timescale = 0 to pause every linecode in one update function. Right?
No. You can disable the script if you want Update to stop running.
I think Time.timeScale
only affects Time
elements; so if you don't use Time.deltaTime
or some other element of Time
, then you won't have anything affected by it.
I'm a little puzzled out on that one. I think when timeScale is null, Update is called and deltaTime is fixed (0.02, something like that), but the animation and the physic is stopped. You should use a coroutine like that :
while( Application.isPlaying() )
{
if( !isPaused )
$$anonymous$$yUpdate();
yield null;
}
I'm not convinced it's the good solution so this is not an answer. Tell me (or someone else) if I'm correct and I'll move it.
Answer by Wolfram · Jun 20, 2012 at 12:23 AM
Setting Time.timeScale to 0 will pause anything that is framerate independent. These are primarily all physics and time-dependent functions, rigidbody forces and velocities, and as an additional result the execution of FixedUpdate() will be halted. But also animations, and any transformations you put in Update() that are weighted by Time.deltaTime, which will also make them framerate independent: no matter how good or bad your framerate is, a rotation scaled by Time.deltaTime will always appear to take the same time.
The execution of Update() itself is unaffected by Time.timeScale, since they are unrelated. Update() is called as often as possible, as fast as your machine can render (unless you activated VSync, then the upper limit is 60fps). The game will seem to be frozen, since all time related things have been stopped. However, the game will still render, hence Update() will still be executed.
Also, when queried in Update(), Time.deltaTime will be 0 if Time.timeScale is 0. Maybe that wasn't the case in earlier versions of Unity, but in 3.5 it is, and it is the correct behaviour. Note, Time.deltaTime does not reflect the time that has passed since the last frame has been rendered in reality, but instead it is that time scaled by Time.timeScale.
However, if you don't scale your transformations in Update() with Time.deltaTime, they will be framerate-dependent, since such a rotation (for example) will be faster for faster framerates, and slower for slow framerates, since each time Update() is called (which is per definition once for every rendered frame) the same amount of rotation is applied.
You can stop the execution of FixedUpdate() with Time.timescale=0
You cannot stop the execution of Update()/LateUpdate(), unless you disable the script.
EDIT: all accepted answers in the link that @Berenger provided contain vital information that will help you understand what's going on when messing with Time.timeScale, and also how you can still control your game if it is set to 0, how to "truly" pause your game (although it might still render as fast as it can, so the GPU still has to work), and so on.
EDIT2: fixed the confusion concerning what Time.deltaTime expresses, resulting from a badly written setnence.
EDIT3: note as @Eric5h5 mentioned in the comment below, you can use Application.targetFrameRate
to influence how often Update() is being called. However, you cannot set it to 0 (well, you can, but it has the same effect as disabling it with -1). You can set it to 1, which will call Update() exactly once per second (but the physics engine will continue at normal speed in the background) (You'll need to set the "Maximum allowed timestep to 1 in this case, otherwise the value returned by Time.deltaTime will be too small). Note there is also Time.captureFramerate, which ensures a "simulated realtime" of a certain fps, independently from your actual framerate you can achieve. The time/physics engine will also use the desired fps as a basis, ignoring realtime, so for the default setting of "Fixed Timestep"=0.02, FixedUpdate() will be called exactly 50x (and Update() exactly Time.captureFramerate times) in one "simulated" second, no matter how long the rendering of these frames actually took.
EDIT4: Note that Time.deltaTime will not be correctly set to 0 if Time.timeScale is set to 0 too early (=in Awake, Start, or the very first call to FixedUpdate/Update/LateUpdate. OnGUI is fine). See comments.
Vsync doesn't have any upper limit, it depends on the display, which is the whole point. 60Hz is common, but not the only possibility. Application.targetFrameRate will also attempt to limit how often Update runs.
Also, when queried in Update(), Time.deltaTime will be 0 if Time.timeScale is 0.
That's not true. Even in Unity 3.5, if TimeScale is 0, deltaTime is .02. It won't be 0.
Note, Time.deltaTime does not reflect the time that has passed since the last frame has been rendered in reality, it reflects the time that has been passed since the last frame for the physics engine
That's not true either. In Update, Time.deltaTime is the time that has passed in reality since the last frame, multiplied by Time.timeScale. If it didn't work like that, it would be completely useless! In FixedUpdate, Time.deltaTime is the time that has passed since the last physics frame; Time.fixedDeltaTime also gives you this information.
Uhm, your right in most cases, but deltaTime IS the time between the last frame and the current rendered frame when timeScale is 1.0. The Physics timestep is a fix timestep (even when just simulated).
1.0 / Time.deltaTime
This reflects your current frames per seconds. For each frame Unity will call Update and LateUpdate, it will render all active cameras and presents the result. If you have a fps of 1000 you can't of course see 1000 frames, but they are rendered, so the framebuffer in your graphics card hold the complete rendered image in memory, 1000 times per second.
Also keep in $$anonymous$$d that Time.deltaTime is a property which returns different values depending on from where you call it. Usually it returns the scaled deltatime, but if you read this value in FixedUpdate it returns the fix-timestep
I did try it, which is why I said it's .02 (also in Windows, at least runtimes; not sure about the editor). I'm aware that 0 would be the expected behavior. There have been questions before from others about why it's .02, so it's not just me.
@Eric5h5: Hm, I still cannot reproduce the behaviour you are seeing. Using this $$anonymous$$imalistic script: http://pastebin.com/QFEsQxX6 I always get a deltaTime of 0 in Update when setting timeScale to 0. This is using an empty project with default settings
I tested: Editor 3.5.2f2 Pro (Windows), Windows-Build (with and without Vsync activated in QualitySettings), Webplayer-Build, Flash-Build, Android-Build. I also tested the script as JS ins$$anonymous$$d of C#.
What are you doing differently?
That's weird. If you set timeScale = 0 in Start, deltaTimes is equal to 0.02, but if you set it after, with a button or a slider or wwhatever, deltaTimes becomes 0 too.