[Solved] Slow everything BUT the Player

I’m working on an action sidescroller(works on a 2D plane, 3D graphics) where the main mechanic is that you can slow down time, i.e. Player stays at the same speed, everything else slows down.

Problem is, when I change Time.timeScale everything slows down.

if (Input.GetKey(KeyCode.Space)) {
     Time.timeScale = 1 / timeSlowMultiplyer; //timeSlowMultiplyer is 4
} else {
     Time.timeScale = 1;
}

To counteract this I tried to change the player’s Time.deltaTime to undo the effects of the time scale

controller.Move(velocity * (Time.deltaTime/Time.timeScale));

This makes three problems:

  1. Character jumps about 3 times as high in slowmo than normal.
  2. Upon activation while beginning to move, the player sort of jumps to max move speed. (I have SmoothDamp on my movement)
  3. Accelerating to max move speed takes longer. (Probably also because of SmoothDamp)

Thanks for taking the time to read this!

Make it so that your code reads this. Just a suggestion I thought of:

controller.Move(velocity * (Time.deltaTime + (1.0-timeScale)));

Noting: this assumes that your normal timeScale is 1.0. How it works:
essentially, what you want is to slow down time, but have the player move at normal speed… This can be represented with this small formula:

fullVelocity = actualVelocity * ( deltaTime + inverse of timeScale )

What this does? since the velocity is multiplied by 0.4 by timeScale, adding deltaTime + 1.0-timeScale effectively gives you a 1.6 multiplier to correct that for ONLY the player. (This would work for everything else too. ;))

Give this a shot and let me know how it goes. :slight_smile:

by timeScale you mean Time.timeScale right?

controller.Move(velocity * (Time.deltaTime + 1-Time.timeScale));

Moves normal when it’s not active
When it is the player moves SUPER fast and jumps reaaallyyy high.

I do get what you mean by the player jumping really high and superfast. Yes, timeScale is Time.timeScale in unity, i simply used the word for the pseudo-code example I gave. :slight_smile:

Ok, made an amendment, some of the code was incorrect:

controller.Move ( velocity * (Time.deltaTime * (1 + (1.0-Time.timeScale) ) ) );

The differences I have made are these:
Essentially, our previous formula:
fullVelocity = actualVelocity * ( deltaTime + inverse of timeScale )
Should actually be this:
full velocity = actual velocity * (time delta * (1 + (1-timeScale) ) )
What it does? :smile:
First… when Time.timeScale is 1.0, everyhting is normal. what we want is to keep the player at 1.0, but slow down everything else.
To do it, we need to multiply the slowed-down velocity by 1 + (1-time scale)

Example: say you have slowed down time so timeScale reads 0.4. what we do is add the inverse of that to 1 to get our number (in this case, the 1.6 multiplier mentioned earlier in my previous posts) The code above does exactly that.

1 Like

Now when slowmo is active the player is moving faster but still slower than what normal speed speed should be, and also jumping higher than it should be but not as high as my original method.

Here, let’s try again, shall we? :smile:

controller.Move(velocity * (Time.deltaTime + (1.0-timeScale)) )

See if this works! I might as well try slow-mo myself, not only to help you, but just for fun… :wink: That’s for another time though, maybe tomorrow I can get a simple slow-mo example working. :slight_smile:

Wait hang on, are you saying the player’s slower but somehow, your jump height’s higher? That doesn’t sound right… :smile:

Using your new code: super fast problem happening again, jumping also super high.

Earlier I meant the player is moving faster than unchanged movements when timescale is slowed, but slower than what it should be.

1 Like

PROBLEMS SOLVED! BIG THING I DIDN’T REALIZE! my gravity “velocity.y += gravity * Time.deltaTime” was affected by deltaTime and i didn’t apply the corrections to it which is why the player kept jumping so high.

Also:
I have changed my approach and made everything have a different time scale.
I have a public class to store the variables

public class TimeScale {
    //default timescales
    public static float player = 1;
    public static float enemies = 1;
    public static float global = 1;
}

so I can access the variables wherever i want

        if (Input.GetKey(KeyCode.Space)) {
            TimeScale.global = 1 / timeSlowMultiplyer;
        } else {
            TimeScale.global = 1;
        }
controller.Move(velocity * Time.deltaTime * TimeScale.player);

this will probably help in the long run for me :smile:
thanks to FuzzyQuills for helping!

You’re welcome! Good to hear you solved it! :slight_smile:

full velocity = actual velocity * (time delta * (1 + (1-timeScale) ) ) THIS!! this worked for me
Thank you captain falcon <1+2

should velocity be vector or a float?