# [Solved] Slow everything BUT the Player

Discussion in 'Physics' started by ArachnophobicSpyder, May 6, 2015.

1. ### ArachnophobicSpyder

Joined:
May 6, 2015
Posts:
5
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.
Code (CSharp):
1. if (Input.GetKey(KeyCode.Space)) {
2.      Time.timeScale = 1 / timeSlowMultiplyer; //timeSlowMultiplyer is 4
3. } else {
4.      Time.timeScale = 1;
5. }
To counteract this I tried to change the player's Time.deltaTime to undo the effects of the time scale
Code (CSharp):
1. 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!

2. ### FuzzyQuills

Joined:
Jun 8, 2013
Posts:
2,871
Make it so that your code reads this. Just a suggestion I thought of:
Code (csharp):
1. 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.

3. ### ArachnophobicSpyder

Joined:
May 6, 2015
Posts:
5
by timeScale you mean Time.timeScale right?
Code (CSharp):
1. 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.

4. ### FuzzyQuills

Joined:
Jun 8, 2013
Posts:
2,871
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.

5. ### FuzzyQuills

Joined:
Jun 8, 2013
Posts:
2,871
Ok, made an amendment, some of the code was incorrect:
Code (csharp):
1.
2. controller.Move ( velocity * (Time.deltaTime * (1 + (1.0-Time.timeScale) ) ) );
3.
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?
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.

zeimhall likes this.
6. ### ArachnophobicSpyder

Joined:
May 6, 2015
Posts:
5
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.

7. ### FuzzyQuills

Joined:
Jun 8, 2013
Posts:
2,871
Here, let's try again, shall we?
Code (csharp):
1. 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... That's for another time though, maybe tomorrow I can get a simple slow-mo example working.

Wait hang on, are you saying the player's slower but somehow, your jump height's higher? That doesn't sound right...

8. ### ArachnophobicSpyder

Joined:
May 6, 2015
Posts:
5
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.

Wander- likes this.
9. ### ArachnophobicSpyder

Joined:
May 6, 2015
Posts:
5
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
Code (CSharp):
1. public class TimeScale {
2.     //default timescales
3.     public static float player = 1;
4.     public static float enemies = 1;
5.     public static float global = 1;
6. }
so I can access the variables wherever i want
Code (CSharp):
1.         if (Input.GetKey(KeyCode.Space)) {
2.             TimeScale.global = 1 / timeSlowMultiplyer;
3.         } else {
4.             TimeScale.global = 1;
5.         }
Code (CSharp):
1. controller.Move(velocity * Time.deltaTime * TimeScale.player);
this will probably help in the long run for me
thanks to FuzzyQuills for helping!

10. ### FuzzyQuills

Joined:
Jun 8, 2013
Posts:
2,871
You're welcome! Good to hear you solved it!

11. ### zeimhall

Joined:
Jun 30, 2017
Posts:
3
full velocity = actual velocity * (time delta * (1 + (1-timeScale) ) ) THIS!! this worked for me
Thank you captain falcon <1+2

12. ### BoyHiddenInTheLeaves

Joined:
Sep 21, 2016
Posts:
2
should velocity be vector or a float?