29
\$\begingroup\$

I'm confused about these two methods in the Unity framework. Both make the player object move, stop, change direction, etc. When should one be used over the other and when is one appropriate?

\$\endgroup\$
3
  • \$\begingroup\$ Linked: gamedev.stackexchange.com/questions/118711/… \$\endgroup\$
    – House
    Commented May 3, 2016 at 15:41
  • \$\begingroup\$ @Byte56 both questions are asking about different things \$\endgroup\$
    – Robert
    Commented May 5, 2016 at 17:32
  • 1
    \$\begingroup\$ Different, but related. That's why they're just linked and not duplicates. Show it shows up in the linked column on the right. \$\endgroup\$
    – House
    Commented May 5, 2016 at 17:33

5 Answers 5

16
\$\begingroup\$

You'd use velocity to move the object at a constant rate (for example a bullet) and AddForce() to add movement (for example a spaceship thruster). Also note there are two "types" of movement; force and impulse. For a spaceship thruster you'd use impulse.

\$\endgroup\$
6
  • 5
    \$\begingroup\$ Can you describe why you'd prefer impulses for a spaceship thruster? This may actually be a non-ideal fit if you're applying gradual acceleration over time, rather than instantaneous changes in momentum due to things like weapon impacts. Applied over a time window you'll generally want force (or acceleration if you don't want mass to be a factor) while instantaneously you'd use impulse (or, correspondingly, velocityChange) \$\endgroup\$
    – DMGregory
    Commented Dec 17, 2015 at 14:21
  • \$\begingroup\$ @DMGregory Yeah, it depends on the kind of force you want to add. In my example of the spaceship thruster, which is a momentary burst of energy then impulse is the correct choice. \$\endgroup\$
    – trojanfoe
    Commented Dec 17, 2015 at 14:23
  • 2
    \$\begingroup\$ It wasn't immediately clear whether you meant a short firing of an attitude jet or the continuous burn of a main engine ("thruster" is used a bit generically in sci-fi at times), so I thought I should clarify lest someone try using impulses for a rocket booster. ;) \$\endgroup\$
    – DMGregory
    Commented Dec 17, 2015 at 14:30
  • \$\begingroup\$ @DMGregory Indeed; my space tech terminology is largely based on films :) \$\endgroup\$
    – trojanfoe
    Commented Dec 17, 2015 at 14:32
  • 1
    \$\begingroup\$ @trojanfoe Go play KSP. Like, right now. \$\endgroup\$ Commented Dec 17, 2015 at 21:13
40
\$\begingroup\$

Although there's already an accepted answer, I think there are some additional details worth covering.

Using Velocity

When you set velocity, you're overriding absolutely everything else that might affect that object's movement. In some situations this is desirable, such as setting the initial velocity of a bullet once at the moment it's fired, as in trojanfoe's example. Just be wary, because when used in the wrong situations it can cause issues:

  • If multiple sources/scripts try to modify the same Rigidbody's velocity by setting it directly (ie. body.velocity = foo), then whichever one runs last wins, and the others have zero effect. This can lead to order of update bugs, in particular causing entities to hover or fall slowly (because downward acceleration due to gravity gets overridden before it can accumulate)

  • If you're setting velocity every frame, collisions with other objects can be a bit weird. It's as though your object is being propelled by an engine with infinite torque - no matter how much velocity it loses on an impact, it's back up to top speed on the very next physics step, and its velocity isn't deflected away from the impact. This can lead to launching objects you collide with, or small objects being able to push huge ones much more easily than it seems like they should, or objects sliding slowly along static barriers instead of deflecting away/along them.

Both of these effects can be desired sometimes. For example, when I'm making Kinect games and I want the player's virtual avatar's limbs to be able to interact with the physics scene, I usually move those bodies using direct velocity setting. Because the player's actual hand is in a known place and didn't slow down from collision with that virtual object, their virtual hand needs to do the same to stay in alignment, so in this case we actually want to override all other physics effects to get it there.

AddForce and Friends

AddForce and similar helper functions, by contrast, are made to cooperate with everything else going on in the physics world. If multiple sources/scripts AddForce to a Rigidbody, all of those effects get added together to create a net change in the object's movement (which, depending on how it's calculated, may also be order-independent). This helps avoid one script completely stomping some other physics effect.

AddForce comes in four flavours by specifying the optional ForceMode parameter, which are useful for different things:

ForceMode       |   Use
-----------------------------------------------------------------------
Force (default) |   Accelerate an object over 1 time step, based on its mass.
                |   Units: Newtons = kg * m/s^2
                |
Acceleration    |   Accelerate an object over 1 time step, ignoring its mass. (like gravity)
                |   Units: m/s^2
                |
Impulse         |   Instantaneously propel an object, based on its mass
                |   Units: N * s = kg * m/s
                |
VelocityChange  |   Instantaneously propel an object, ignoring its mass
                |   (like body.velocity = foo, except multiple scripts can stack)
                |   Units:  m/s

If you're trying to model a continuous push over time (eg. something you're applying every FixedUpdate), like a car driving or a rocket burning or a gravity well pulling, you want Force or Acceleration. (Depending on whether you want heavy objects to accelerate slower)

If you're modelling a sudden, sharp change in motion, like firing a bullet, recoiling from an explosion, or bouncing off a barrier, then you more likely want Impulse or VelocityChange.

Using AddForce helps you achieve more physical realism, but it can also require that you spend more time thinking through the physics of your behaviour. For instance, if you want your body to have a finite acceleration up to a target speed, so that it reacts more realistically to collisions than setting the velocity every frame, you'll probably want a calculation similar to this helper function:

public static void AccelerateTo(this Rigidbody body, Vector3 targetVelocity, float maxAccel)
{
    Vector3 deltaV = targetVelocity - body.velocity;
    Vector3 accel = deltaV/Time.deltaTime;

    if(accel.sqrMagnitude > maxAccel * maxAccel)
        accel = accel.normalized * maxAccel;

    body.AddForce(accel, ForceMode.Acceleration);
}

The reason I call all of these "helper functions" is that technically you could achieve all the same ends with:

 body.velocity += suitablyCalculatedDeltaV;

(I think. It's possible Unity's PhysX/Box2D-based physics solvers buffer changes through AddForce separately, but I haven't seen obvious consequences of this)

So at the end of the day, what these functions really get us is clarity of intent. When I want to apply a gradual force, I don't need to remember to multiply my deltaV by Time.deltaTime and divide by mass, I just say I want ForceMode.Force and it's handled in a correct & consistent way. And when I or someone else comes to iterate on my code later, it's immediately clear what I meant, without needing to decode the time and mass calculations to figure it out.

\$\endgroup\$
0
6
\$\begingroup\$

In addition to trojanfoe's answer, Angry Birds vs Car Racing. Two major and different examples of these methods (AddForce and velocity respectively). For example, in Angry Birds use of velocity is little more difficult as you would have to set Projectile trajectory by your self, like,

When I use AddForce in Angry Birds, I would use,

_birdRigidbody.AddForce(new Vector2(5,5));

While when I use velocity then I would handle trajectory using

x = v*t*Cos(theta) y = v*t*Sin(theta) - 0.5 * g * t *t

Or something like this.

While in Car Racing game you would have to control speed all the time, not like Angry Birds i.e. Shoot and all. So in that scenario handle velocity is more useful than AddForce.

Hope you understand. At least little bit.

\$\endgroup\$
1
  • 1
    \$\begingroup\$ Your AngryBirds example should probably use an instantaneous change in momentum (eg. Impulse or VelocityChange) when the slingshot is released, rather than the default ForceMode.Force which simulates its effect over a time window. You can tune the numbers to get equivalent behaviour out of either approach, but if you change your fixed time step the force solution will have a different output (since it's integrating the force over a longer or shorter time interval) while the impulse remains consistent as desired, because it represents just the moment of release. \$\endgroup\$
    – DMGregory
    Commented Dec 17, 2015 at 14:31
0
\$\begingroup\$

Rigidbody Velocity and Rigidbody Addforce are two confusing functions in Unity 3D and often beginners fail to understand their difference. In This Article, we are going to discuss the difference between RigidBody.velocity and RigidBody.addforce.

In both cases, whether it is Addforce or velocity function we are going to use the term force to explain them.

When we are using Rigidbody.velocity , then, in that case, we are adding force to our object but this force will only move the object unless and until we keep applying force.

For example

body.velocity= new Vector3(0,0,5);

Let say you have added 5f in z position and that force will be added when you'll press W key. So When you will press W key the object will instantly start at the speed of 5. It's like the same if you are adding force using this function on a car, that car will start at the speed of 5.

body.velocity= new Vector3(0,0,200);

And if you let say change the value to 200 and then after saving press W. Car will start running at the speed of 200 from starting which is not possible in real world.

Now If you talk about Rigidbody.addforce

By Continuing our Car example. if you add the force of 200 to car

body.addforce(0,0,200);

The Car will not start moving at the speed of 200 if we press W but it starts from slow and then increases its speeds and stops according to the value of Drag.

Rigidbody.addforce starts slow and then speed up, just like you are dragging a heavy table, first you will start pushing that table, the table will just move a little bit from its position but if you keep pushing that table it will starting moving & if you leave that table it will cover some distance depending on surface and that's the same rigidbody.addforce do.

You can use Rigidbody.velocity where you just want to move your object to react instantly like player jump & the result of that force will vanish just after the jump and you can use Rigidbody.addforce where you need slow start and then the continuous movement like a rocket. If you use Rigidbody.addforce in jump , Player/Object will remain in space for a while and then will come back to ground .

(source)

\$\endgroup\$
1
  • 1
    \$\begingroup\$ You should at least try and adapt your post to the format of a Stack Exchange answer :) \$\endgroup\$
    – Vaillancourt
    Commented Sep 5, 2017 at 23:41
0
\$\begingroup\$

Adding to existing answers. From what I tested, it seem AddForce is buffered PER script. Meaning doing :

r.AddForce(Vector3.one);
r.velocity = Vector3.zero;

In the same script, will stop your rigidbody as you expect it to.

But if you do the same, each line in a different script, making sure they run in the correct order using Script execution order panel of Unity. It will keep moving.

However, replacing AddForce by his equivalent:

float v = (force / rigidbody.mass) * Time.fixedDeltaTime;
rigidbody.velocity += v;

Make it behave as expected.

I don't know if I missed something, because this is a quite strange behavior.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .