Search Unity

[Solved] Slow everything BUT the Player

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

  1. ArachnophobicSpyder

    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

    FuzzyQuills

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

    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

    FuzzyQuills

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

    FuzzyQuills

    Joined:
    Jun 8, 2013
    Posts:
    2,869
    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? :D
    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

    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

    FuzzyQuills

    Joined:
    Jun 8, 2013
    Posts:
    2,869
    Here, let's try again, shall we? :D
    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... :D
     
  8. ArachnophobicSpyder

    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.
     
  9. ArachnophobicSpyder

    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 :D
    thanks to FuzzyQuills for helping!
     
  10. FuzzyQuills

    FuzzyQuills

    Joined:
    Jun 8, 2013
    Posts:
    2,869
    You're welcome! Good to hear you solved it! :)
     
  11. zeimhall

    zeimhall

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

    BoyHiddenInTheLeaves

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