Search Issue Tracker

Won't Fix

Votes

2

Found in

2019.4

2020.1.17f1

2020.2

2021.1

2021.2

Issue ID

1310653

Regression

No

Vector3.SmoothDamp behaves differently between positive and negative velocity

Scripting

-

How to reproduce:
1. Open the user's attached project "SmoothDampBugDemo"
2. Open the "SmoothDampTestScene" scene
3. Enter Play Mode
4. Press the Right Arrow key until the "SmoothDamp Change Velocity" is a positive number
5. Let go of the key
5. Press the Left Arrow key until the "SmoothDamp Change Velocity" is a negative number
5. Let go of the key

Expected results: Both times the GameObject either comes to a halt or continues to move after letting go of the key
Actual results: The GameObject continues to move if the velocity is a positive number and instantly stops if it is a negative number

Reproducible with: 2019.4.20f1, 2020.2.0b6, 2021.1.0b8, 2021.2.0a6
Could not test with: 2018.4.32f1 (SmoothDamp not available)

  1. Resolution Note:

    This method has always been like that. It based on Programming Gem 4 SmoothDamp but with a check to avoid overshooting. Unfortuantelly we cannot change this behaviour since many project could rely on this.

    The only workaround for you is to create your own version of smooth damp without the overshooting check.

    public static float SmoothDampUnity(float current, float target, ref float currentVelocity, float smoothTime, float maxSpeed, float deltaTime)
    {
    // Based on Game Programming Gems 4 Chapter 1.10
    smoothTime = Mathf.Max(0.0001F, smoothTime);
    float omega = 2F / smoothTime;

    float x = omega * deltaTime;
    float exp = 1F / (1F + x + 0.48F * x * x + 0.235F * x * x * x);
    float change = current - target;
    float originalTo = target;

    // Clamp maximum speed
    float maxChange = maxSpeed * smoothTime;
    change = Mathf.Clamp(change, -maxChange, maxChange);
    target = current - change;

    float temp = (currentVelocity + omega * change) * deltaTime;
    currentVelocity = (currentVelocity - omega * temp) * exp;
    float output = target + (change + temp) * exp;

    /*
    // Prevent overshooting
    if (originalTo - current > 0.0F == output > originalTo)
    {
    output = originalTo;
    currentVelocity = (output - originalTo) / deltaTime;
    }
    */

    return output;
    }

Comments (4)

  1. kureysalp

    Mar 15, 2024 17:17

    Won't fix? It seems people works on Unity doesn't deserve their money.

  2. jadelion1235

    Mar 26, 2023 12:13

    This needs resolving, the code provided here has exactly the same issue and does not smooth negative values.
    If this is fixed it will just make projects run better overall, doesn't make sense not to fix it.

  3. PandaArcade

    Mar 26, 2023 07:13

    Won't Fix... because it might make people's code work as intended. Hahaha

    At least mention this issue in the docs, and stop wasting our time!

  4. MoonBeam91

    Jul 09, 2022 18:01

    The presented code still doesn't work for negative values. I have a dragon that roll based on mouse X axis. the dragon is only rolling left (positive values) and not rolling right. Mathf.Lerp seems to be working fine

Add comment

Log in to post comment

All about bugs

View bugs we have successfully reproduced, and vote for the bugs you want to see fixed most urgently.