Slippery Movement

So far I’ve been using

GetComponent().AddForce(transform.forward * 100);

to move my character when I press the up key but the movement is really slippery and has too much inertia in the previous direction when I change course.

Increasing the drag doesn’t really fix this. I know I could just set the position but this may cause my character to clip through objects.

How can I fix this? (This is for 3D movement)

A lot of games like to add extra force when you are trying to move in the opposite direction than you are currently travelling. Try doing something like that.

Acceleration = Force / Mass.

If you want to accelerate faster, you must increase the force, or decrease the mass of the object. (Acceleration just means change in velocity, so it includes deceleration as well).

2 Likes

That’s not the issue.

It is the issue. To slow down your object you must apply a force in the opposite direction of motion.

1 Like

6903437--808253--upload_2021-3-4_22-41-29.png
Let’s say you are currently travelling in the direction indicated by the dark blue arrow. You want to change direction to be travelling in the direction indicated by the light blue arrow.

In order to do this, you need to add a force in the direction of the red arrow. To further break the red arrow down, there is the component indicated by the pink arrow in the direction you want to be going. There is also the component indicated by the small green arrow which you need to counteract your existing velocity in the direction of the dark blue arrow.

Without that green component, you will continue sliding in the direction of the dark blue arrow due to inertia, as you described, and will end up going up and to the right. So the answer is to apply a force in the direction of the green arrow, as well as the pink arrow you are probably using currently.

4 Likes

Thanks for the info! Greatly appreciated.

Increasing the drag enough will fix it, but you may need to increase the force added to make up for the extra drag. Or you could add code-drag only when the button is held. That way it will coast normally when you let go:

if(acellButtonPressed) {
  myRB.velocity*=0.6f; // massive drag if over several frames
  // does the same thing as AddForce:
  myRB.velocity+=transform.forward*100*Time.deltaTime;
}
1 Like

I like the idea of adding a counter force, but now the question becomes how do I obtain what the initial direction was after I rotate my camera say 2 degrees?

Rigidbody velocity is Rigidbody velocity. you’ll basically just want to apply a force counter to whichever component of the current velocity is not in the direction you are trying to go

Using local coordinates is like taking a hammer to the problem, but it will work to isolate the “way I’m going” part of the old vector from the rest. The idea is you figure out which way you want to move and call that your local space – that direction counts as your +z. Then convert your current velocity into it. Now +z is good, and x and y are going the wrong way and should be reduced. Then convert the result back to global. Ex (80% of this is standard “to local, adjust, back to global”. It’s also from memory):

Quaternion wantDirection=transform,forward; // assuming accel is only in facing direction
Vector3 curVelLocal=Quaternion.Inverse(wantDirection)*myRB.velocity;

// crush the x and y in some way:
curVelLocal.x=Mathf.MoveTowards(curVelLocal.x,0,1.0f*Time.deltaTime);
curVelLocal.y=Mathf.MoveTowards(curVelLocal.y,0,1.0f*Time.deltaTime);

// convert back to global:
Vector3 oldVelAdjusted=wantDirection*curVelLocal;
// add to it, or just put it back (so we can use AddForce):
myRB.velocity=oldVelAdjusted;

The overall effect is like drag only for “sideways”, none for forward. I used MoveTowards for fun.

1 Like

Thank you everyone! Overall I got it figured out (thanks to your help)

This ^ ^ ^ you need the apply the force necessary to correct the velocity to what the user wants. An example:

https://discussions.unity.com/t/831069/9