- Home /
Can't clamp velocity
Hello. I'm moving my gameobject around using the following line of code: rb.AddForce(Quaternion.Euler(-slopeAngle, cam.eulerAngles.y, 0) * inputVector * moveSpeed, ForceMode.Impulse);
Long story short, for my purposes AddForce seems to be the only viable option to move the character (as opposed to setting the velocity or position manually)
The obvious problem with this is that force is just added forever and the character accelerates to infinity and beyond
the first obvious solution would be to increase the drag, but the problem is I want jumping to be snappy, but high drag prevents this
So the second obvious solution would be to clamp the velocity, which I tried with the following line: rb.velocity = Vector3.ClampMagnitude(rb.velocity, maxSpeed);
but for some reason I still get some velocity. even if I set maxSpeed to zero. I tried putting this line in Update, FixedUpdate, LateUpdate, and a Coroutine with WaitForFixedUpdate, but no dice. I tried to manually clamp the velocity's x, y, and z using Mathf.Clamp, with no luck. Could someone lend a hand?
Answer by Jjules · Jun 25, 2018 at 10:41 AM
I got it! This is a marriage of the two ideas given to me by @Captain_Pineapple : rb.AddForce(Quaternion.Euler(-slopeAngle, cam.eulerAngles.y, 0) * inputVector * (maxSpeed - rb.velocity.magnitude) * moveSpeed * Time.deltaTime, ForceMode.Impulse);
Since you can't apply a complete clamp after applying force, you have to slow down how much force you apply, and this scales with how close you are to the max speed. The movement is beautifully smooth, plays nice with physics, and had no camera jitter. Thank you everyone for your help!
That is indeed a smart solution. I feel kinda dumb now :D
Answer by Captain_Pineapple · Jun 25, 2018 at 08:54 AM
Hey there,
there a 2 things that you should probably do:
First thing is to apply force relative to Time.deltaTime and to do it in FixedUpdate.
Secondly you could try the following to clamp the velocity:
if(rb.velocity.magnitude < maxSpeed)
{
rb.AddForce(Quaternion.Euler(-slopeAngle, cam.eulerAngles.y, 0) * inputVector * moveSpeed * Time.deltaTime, ForceMode.Impulse);
}
or you could use an "inconsistent drag" like this:
if(rb.velocity.magnitude > maxSpeed)
{
rb.velocity = rb.velocity*0.99f;
}
The latter will not give you a "hard" maxVelocity level but rather an increased damping the faster you get.
Hope this helps.
A few things: 1. Funny enough, I actually have * Time.deltaTime in my code, but I removed it when I posted the question because I was afraid it was wrong LOL. Thanks for the clarification 2. The second solution unfortunately has the same problem I faced in the original question when I clamp the velocity or magnitude, just like in the original post 3. The first solution is a very interesting case! I had a fear that it would cause jitter in my movement , but it worked. The only catch is, it does introduce some jitter; not in my player however but in the camera's smooth follow
Now camera jitter is a very common problem, and I've already taken all the measures necessary to remove it, like making sure the physics is in FixedUpdate, making sure the camera follow is in LateUpdate, and making the player's rigidbody interpolate and continuous dynamic. Despite all this, this camera jitter seems to be more resilient than the rest, and I've yet to make it go away
This is a totally different problem now, I'll see if I can get this sorted out on my own, I just wanted to leave some details for anyone who stopped by this question in the future. Thank you for going out of your way to lend a hand!
Answer by RetroGeek46 · Jun 25, 2018 at 06:41 AM
Firstly check that the clamping should be done after the application of forces, that is near the end of update function. After that, just male sure that your maxSpeed value is not being overridden by inspector values.
Thank you for your response. I tried putting it in FixedUpdate, LateUpdate, A Courutine that waits for the end of FixedUpdate, and I tried putting it both at the beginning and the end of Update, with no luck. I even tried putting it in all those spots at once out of desperation, to no avail. And thanks for checking; my maxSpeed value is set to 0 in the inspector.
raising the max value does make it speed up (going from way too fast to stupid fast), so the code is having some effect, but it cant clamp to the value I tell it to
Your answer
Follow this Question
Related Questions
Rigidbody character controller can't walk on stairs 0 Answers
Velocity Behavior Question 0 Answers
Moving a player with Rigidbody 2 Answers
Unity3D: Get Velocity after collision 0 Answers
Problem Trying to Apply Non-Kinematic Velocity to Rigidbody 0 Answers