Search Unity

Applying Drag Unity Style

Discussion in 'Scripting' started by GibTreaty, Aug 30, 2013.

  1. GibTreaty

    GibTreaty

    Joined:
    Aug 25, 2010
    Posts:
    792
    So I've recently discovered how to apply drag exactly the way Unity seems to be doing it. Sorry if this has been shown on the forums before but I've been trying to tackle this for a long time with no good solution.

    The first one I came across here http://www.leadwerks.com/werkspace/topic/4385-physics-how-does-unity-calculate-drag/
    did not have the right solution.

    Code (csharp):
    1.  
    2. dragForceMagnitude = velocity.magnitude ^ 2 * drag;
    3. dragForceVector = dragForceMagnitude * -velocity.normalized
    The result is that the object never stops. I've been doing some fiddling around with some of my old drag code which looked like
    Code (csharp):
    1.  
    2.         velocity -= velocity.normalized * drag * Time.deltaTime;
    3.  
    4.         if(x > 0) if(velocity.x < 0) velocity.x = 0;
    5.             else if(x < 0) if(velocity.x > 0) velocity.x = 0;
    6.  
    7.         if(y > 0) if(velocity.y < 0) velocity.y = 0;
    8.             else if(y < 0) if(velocity.y > 0) velocity.y = 0;
    9.  
    10.         if(z > 0) if(velocity.z < 0) velocity.z = 0;
    11.             else if(z < 0) if(velocity.z > 0) velocity.z = 0;
    12.  
    It works but when I compared it on an AnimationCurve to a rigidbody with the same mass, drag and velocity, mine would slow down at a constant/linear rate. The rigidbody would slow down at a curved rate.

    After all of my fiddling around, I came up with the solution!
    Code (csharp):
    1.  
    2. velocity -= Vector3.ClampMagnitude(velocity, 1) * drag * Time.deltaTime;
    3.  
    A full script example looks like

    THE ANSWER ~ Not anymore; Check Below
    Code (csharp):
    1.  
    2. public class PhysicsObject  : MonoBehaviour {
    3.     public Vector3 velocity;
    4.     public Vector3 force;
    5.  
    6.     public float mass = 1;
    7.     public float drag;
    8.  
    9.     void FixedUpdate() {
    10.         Vector3 acceleration = force / mass;
    11.  
    12.         velocity += acceleration * Time.deltaTime; //Apply acceleration
    13.         velocity -= Vector3.ClampMagnitude(velocity, 1) * drag * Time.deltaTime; //Apply drag
    14.  
    15.         transform.Translate(velocity * Time.deltaTime, Space.World);
    16.         //or
    17.         //transform.Translate(velocity * Time.deltaTime + (.5f * acceleration * Time.deltaTime * Time.deltaTime), Space.World);
    18.  
    19.         force = Vector3.zero;
    20.     }
    21. }
    22.  
    Edit:
    Not sure why it doesn't work anymore but now I've found that you have to do
    Code (csharp):
    1.  
    2. void FixedUpdate() {
    3. velocity -= velocity * drag * Time.delaTime;
    4. }
    5.  
    Using ClampMagnitude doesn't seem to do the job anymore, not sure why it worked then but not now. Doing it this way does in fact work though. You can "move" the object with transform.Translate(velocity * Time.deltaTime) in either Update or FixedUpdate and it will move correctly.
     
    Last edited: Oct 18, 2013
    khaled24, mr_president and Nonakesh like this.