Factoring in drag and mass of an object. I’m trying to move my rigidbody player at a certain velocity based on their movement input and a set movespeed. Like, I want the speed of the rigidbody to be this after it accelerates up to that desired speed. I would addforce (calculated from this formula I need) until it reaches the desired velocity. Any ideas?
From an engineer’s perspective who has used a rigidbody for character movement, I would suggest looking at PID controller logic, more specifically a simplified PD logic. It is easy to ‘tune’ and simpler than ‘simulating’ the forces in an algorithm (which would be back-calculating what Unity is calculating).
In this case it would take in a desiredVelocity and output a force in vector form to apply to the rigidbody. For tuning the ProportionalGain and DerivativeGain values would be increased until the desired response is achieved (but not too far, due to deltaTime step limitations). Here is pseudocode quasi-copied from link text
float ProportialGain = 5; //increase to improve response time
float DerivativeGain = 3; //increase to improve smoothness
Vector2 previousVelocity_error = Vector2.zero;
Vector2 desiredVelocity; //set from interpreting player inputs
FixedUpdate()
{
Vector2 measuredVelocity = new Vector2(Rigidbody.velocity.x, Rigidbody.velocity.z);
Vector2 error = desiredVelocity - measuredVelocity;
Vector2 proportional = error;
Vector2 derivative = (error - previousVelocity_error) / Time.DeltaTime;
previousVelocity_error = error;
Vector2 force = ProportialGain * proportional + DerivativeGain * derivative;
//apply force to rigidbody
}
I’ve posted several methods some time ago over here:
float GetRequiredVelocityChange(float aFinalSpeed, float aDrag)
{
float m = Mathf.Clamp01(aDrag * Time.fixedDeltaTime);
return aFinalSpeed * m / (1 - m);
}
float GetRequiredAcceleraton(float aFinalSpeed, float aDrag)
{
return GetRequiredVelocityChange(aFinalSpeed, aDrag) / Time.fixedDeltaTime;
}
float GetRequiredForce(float aFinalSpeed, float aDrag, float aMass)
{
return GetRequiredAcceleraton(aFinalSpeed, aDrag) * aMass;
}
I just added the 3d variant here that calculates the required force. Though note that this does only work when no other forces are involved. So no friction or collisions, just plain drag. As I explained in the other answer, the final speed is an asymptotic speed, so it can actually take a while until you reach it.
If you actually have to include other forces (gravity, friction, etc.) calculating the required force is usually way too complicated and way to unstable. Like MafiaMoe said, using a PID controller is probably the best solution in such cases.