Search Unity

  1. Unity 6 Preview is now available. To find out what's new, have a look at our Unity 6 Preview blog post.
    Dismiss Notice
  2. Unity is excited to announce that we will be collaborating with TheXPlace for a summer game jam from June 13 - June 19. Learn more.
    Dismiss Notice

Stop forces from acting on object?

Discussion in 'Physics' started by Denisowator, Jan 19, 2019.

  1. Denisowator

    Denisowator

    Joined:
    Apr 22, 2014
    Posts:
    918
    I'm using AddForce to move an object.
    Code (CSharp):
    1. thisRigidbody2D.AddForce(Vector2.up * chargeSpeed, ForceMode2D.Force);
    So the object's velocity doesn't change.

    But I want to have the object fully stop after 1 second. Since velocity isn't being altered, setting Rigidbody2D.velocity to 0 won't do anything.

    Is there a way of removing forces from an object? Or should I be changing the object's velocity to create movement (so that I can just set it to 0 when I need it to stop)?

    P.S. Whether the movement is static or smooth doesn't really matter to me at this stage.
     
    Last edited: Jan 19, 2019
  2. hippocoder

    hippocoder

    Digital Ape

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    Set velocity to Vector2.zero and angularVelocity to 0.
    Set gravityscale to 0 if gravity is acting on it.
     
  3. Denisowator

    Denisowator

    Joined:
    Apr 22, 2014
    Posts:
    918
    Like I said, velocity isn't affected by AddForce. It stays at 0 while the object is moving, so setting it to 0 does nothing.
    Could you suggest a velocity alternative to AddForce so it behaves the same (or at least similarly)?

    e.g.
    Code (CSharp):
    1. thisRigidbody2D.velocity = // Something here
    Also I just realized, apparently adding velocity to the object, doesn't actually make it move.
     
    Last edited: Jan 20, 2019
  4. Denisowator

    Denisowator

    Joined:
    Apr 22, 2014
    Posts:
    918
    Okay, update.

    I did something I tried before that didn't work... And somehow it's working now.
    Code (CSharp):
    1. thisRigidbody2D.AddForce(mouseDir * 0, ForceMode2D.Force);
    So I can stick with my AddForce method for now.

    Also I needed to add some IF checks here and there. Because I left my AddForce that moves the player, inside FixedUpdate right after an IF check that runs until I set a boolean to true. I thought if I set the boolean back to false, the code wouldn't run past that IF check, so the AddForce wouldn't be re-run and cause the player to keep moving after I stopped them... But apparently that wasn't the case. So I just had to put the AddForce into an IF check, checking for the boolean being true.

    Short version:
    I had to change this.
    Code (CSharp):
    1. void FixedUpdate () {
    2.     if (bool == false) {
    3.         //do stuff
    4.     }
    5.  
    6.     thisRigidbody2D.AddForce
    7. }
    Into this.
    Code (CSharp):
    1. void FixedUpdate () {
    2.     if (bool == false) {
    3.         //do stuff
    4.     }
    5.  
    6.     else {
    7.         thisRigidbody2D.AddForce
    8.     }
    9. }
    Now everything is working fine, and the object is stopping after the desired time.
     
  5. Magnas_94

    Magnas_94

    Joined:
    Jan 20, 2019
    Posts:
    5
    Disabling the gameObject and making it active again always seems to work for me,
    Try it !
    Code (CSharp):
    1.   private void RemoveAllForces()
    2.     {
    3.         gameObject.SetActive(false);
    4.         gameObject.SetActive(true);
    5.     }
     
  6. SparrowGS

    SparrowGS

    Joined:
    Apr 6, 2017
    Posts:
    2,536
    *No experience with 2D physics so take what I say with a bit of doubt.

    So velocity is always 0 and you move it with AddForce?
    Sounds like a bug, add force gives you velocity and the object moves through it.
    how are you reading the velocity?

    Code (CSharp):
    1. thisRigidbody2D.AddForce(mouseDir * 0, ForceMode2D.Force);
    2.  
    this should literally do nothing, it's like saying
    Code (CSharp):
    1. thisRigidbody2D.AddForce(Vector2.zero, ForceMode2D.Force);
    2.  
    is setting it kinematic on and off works too?
    if so, you should probably do that because that way you don't have to toggle the entire object and it's children.
     
  7. Denisowator

    Denisowator

    Joined:
    Apr 22, 2014
    Posts:
    918
    I'm reading the velocity by expanding the Rigidbody's "Info" dropdown.

    And you're right, adding a force of "mouseDir * 0" shouldn't work, because it's adding a force with no value in any direction, but it works somehow.

    I've read somewhere that AddForce applies external forces, and that's why it doesn't directly alter the Rigidbody's velocity, though as an object is moving it's velocity should still change in the Info section. Maybe it is a bug, but this happened every time I've ever used AddForce as far back as I can remember.

    I haven't tried using Kinematic, but the object is expected to constantly be colliding with other objects, so setting it to Kinematic even for a second could yield unnatural behaviors.
     
  8. SparrowGS

    SparrowGS

    Joined:
    Apr 6, 2017
    Posts:
    2,536
    I don't recall this being a thing, but maybe it's just a 3D-2D mismatch.
    Did you try Debug.Log()? the inspector window sometimes doesn't update until you refocus on it.
     
  9. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,589
    When you add a force to a body then it doesn't affect the velocity until the simulation runs at which point all the forces added to the body are integrated. You may not see a change in velocity if there are opposing forces i.e. collision, other manually added forces etc. All of that force won't be added to the velocity either, it'll be time-integrated.

    If you add a force as an impulse then it's added to the velocity directly and is the same as adding it to the velocity yourself. You get the full impulse force this way.

    There's some detail here.

    Note: You can see the source-code if you look at "b2Body::ApplyForce" here (line 740) effectively adding the force you add to a total including totalling any torque that would be induced too. Both these linear and angular (torque) forces are added here (lines 206-207) with the linear force be added to velocity (v) scaled by the inverse-mass of the body with the addition of gravity and its scale then scaled by the delta-time (h). In other words, total all user forces then add them during the time-step scaled by the delta-time and the inverse-mass with the addition of gravity. You should see there's no impulse force here, that's added immediately to the velocity if you look at "b2Body::ApplyLinearImpulse" (line 798) above.
     
    Denisowator and SparrowGS like this.
  10. deadbobgames

    deadbobgames

    Joined:
    Feb 3, 2016
    Posts:
    3
    Using Vector3.zero for both the rigidbody.velocity and rigidbody.angularvelocity will stop the object and remove those forces.

    If you want to slow the object down over time, here is an example using the new Input System:

    Code (CSharp):
    1. PlayerInput playerInput;
    2.     float mainThrust = 100f;
    3.     private Vector2 thrustInput;
    4.  
    5.     void ThrustMovement() //Using the new Input System
    6.     {
    7.         //Input Action OnThrust bound to Directional Gamepad with normalized Vector2 processing
    8.         thrustInput = playerInput.actions["OnThrust"].ReadValue<Vector2>();
    9.  
    10.         //Be sure to remove default deadzones on Input Action in the Project Settings > Input System Package
    11.         if (thrustInput.y > 0.1f || thrustInput.y < -0.1f)
    12.         {
    13.             rb.AddRelativeForce(Vector3.forward * thrustInput.y * mainThrust * Time.fixedDeltaTime);
    14.         }
    15.  
    16.         else
    17.         {
    18.             if (rb.velocity.z > 0.05f)
    19.                 rb.AddRelativeForce(Vector3.forward * -mainThrust * 2 * Time.fixedDeltaTime);
    20.             else if (rb.velocity.z < -0.05f)
    21.                 rb.AddRelativeForce(Vector3.forward * mainThrust * 2 * Time.fixedDeltaTime);
    22.             else
    23.                 rb.velocity = Vector3.zero;
    24.         }
    25.     }
    26.  
    27.     private void FixedUpdate()
    28.     {
    29.         ThrustMovement();
    30.         YawMovement(); //Not in this example
    31.         PitchMovement(); //Not in this example
    32.     }
    33.  
    34.     public void OnThrust(InputAction.CallbackContext context)
    35.     {
    36.         thrustInput = context.ReadValue<Vector2>();
    37.     }
    38.    
    39.  
    40.  
    41.  
    42.  
     
    Last edited: Sep 14, 2022
  11. hippocoder

    hippocoder

    Digital Ape

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    Do you set it to zero in FixedUpdate or Update?
     
  12. deadbobgames

    deadbobgames

    Joined:
    Feb 3, 2016
    Posts:
    3
    physics should happen in Fixed Update.