how to get smooth slow motion?

I'm currently using the following script to create slow motion. However it doesn't smooth out the slow motion by adding the frame information for the frames in between the full speed motion and the new slower motion. By this I mean:

full speed has frames A,B,C,D

A true slow motion effect at 50% of real speed would create frames in between the above frames:

A, a, B, b, C, c, D, d

where the lower case frames are exactly halfway between the upper case letters in terms of all object positions and movements.

This is not the case for the below code, instead it does this at 50%

A, A, B, B, C, C, D, D

Where the second A is a repeat of the first A frame, not an effort to figure out the inbetween states of everything.

Is there a way to get true slow motion?

Here's the code I'm using;

   var paused : boolean = false;

function Update () {
   Time.timeScale = .5;
   Time.timeScale = 1;

A very kind soul on the internet gave the answer on here

The gist of it is to add these two lines

  Time.timeScale = 0.5;
  Time.fixedDeltaTime = 0.02F * Time.timeScale;

The fixedDeltaTime is what causes the smoothness to play out. If for whatever reason you need to revert the game back to normal speeds. I apply this after all the calculations are done.

   Time.timeScale = 1;
   Time.fixedDeltaTime = 0.02F ;

Seems to work for me.

Happy coding and hope this helps others.

Setting Time.timeScale to .5 does result in "true" slow motion; no rendered frames are repeated. The problem you're seeing is that physics runs on its own discrete timer, 50 fps by default, which setting timeScale to .5 effectively halves. One thing you can do is to double the physics framerate to compensate. However, this chews up twice the CPU time when you're not using slow motion. Probably a better solution is to turn on interpolation for rigidbodies, in which case they're interpolated smoothly between each physics frame.

Changing Time.timeScale cause Time.deltaTime to scale according to the time scale. For this to have any effect, you must ensure that all your movement/animation made in Update() properly use Time.deltaTime.


function Update()
    transform.Translate(Vector3.forward * Time.deltaTime);

Note that you probably should change Time.fixedDeltaTime as the documentation for Time.timeScale suggests in order for your physics and other fixed time behaviors to work correctly.

You'd maybe think Unity could derive information somehow between two calls to Update but that is not how it works. It is up to you to scale animation with accordance to Time.deltaTime (which unity does scale for you).

That solution, of multiplying Time.fixedDeltaTime, gives me physics glitches when pausing and unpausing my game.

The solution I came up with is to use Time.timeScale and then mimic FixedUpdate behavior in the Update loop using Time.realtimeSinceStartup:

float LastFixedUpdateTime = 0f;

void Start()
	LastFixedUpdateTime = Time.realtimeSinceStartup;

void Update(){
	if(Time.realtimeSinceStartup > LastFixedUpdateTime + Time.fixedDeltaTime)
		LastFixedUpdateTime += Time.fixedDeltaTime;