- Home /
The question is answered, right answer was accepted
How to limit a movement vector without affecting gravity
Hello, I wrote a script to control my spaceship, and I can limit its speed by using Vector3.ClampMagnitude(myRigidbody.velocity). However it affects a gravity and if I move down to the planet's surface my max speed is limited and it is not realistic. My question is how limit my movement vector( I use AddForce to apply it to my rigidbody) but keep gravity vector, which I also apply to rigidbody by using AddForce method, unlimited. Thanks in advance
Answer by Bunny83 · Nov 09, 2018 at 12:41 PM
If your gravity is not "world space" down and you only want to clamp the tangent velocity you can seperate the velocity into the "vertical" / gravity part and the "horizontal" / tangential part.
Of course to do this you have to provide the direction of gravity as a vector for reference.
public Vector3 ClampVelocity(Vector3 aVelocity, Vector3 aGravity, float aMaxTangentialVelocity)
{
var grav = Vector3.Project(aVelocity, aGravity);
var tan = aVelocity - grav;
tan = Vector3.ClampMagnitude(tan, aMaxTangentialVelocity);
return tan + grav;
}
This method basically works the same as "ClampMagnitude" but it removes the velocity part along the gravity direction, clamps the remaining part and adds the gravity part back at the end.
Thank you a lot. The only thing I had to change is to use own Project method.
public Vector3 Project(Vector3 vector, Vector3 onNormal)
{
Vector3 vector3;
float single = Vector3.Dot(onNormal, onNormal);
float dot = Vector3.Dot(vector, onNormal);
vector3 = (single >= $$anonymous$$athf.Epsilon ? (onNormal * ((dot >= 0f) ? dot : 0f)) / single : Vector3.zero);
return vector3;
}
Thus I can also limit a velocity when angle between velocity and gravity direction is more than 90 degrees. And this is what a need.
Answer by swanijam · Nov 06, 2018 at 03:41 PM
You could try limiting the velocity only in non-downward directions.
try this (untested)
Rigidibody rb;
bool separatedDownardVector = false;
Vector3 tempVelocity = rb.velocity;
// removes the y component if the object is moving downward
if (tempVelocity.y < 0f) {
separatedDownardVector = true;
tempVelocity.y = 0f;
}
// clamp the magnitude of the edited velocity.
tempVelocity = tempVelocity.normalized * Mathf.Clamp(0f, maximumSpeed, tempVelocity.magnitude);
// adds the downard vector back, if it was removed earlier.
if (separatedDownardVector) tempVelocity += rb.velocity.y;
rb.velocity = tempVelocity;
Thank you, but my gravity is not directed to vector3.down(vertically down), I have a planet gravity, so I need to remove some vector from velocity but not only y component. Some ideas?