- Home /
How to set velocity of Rigidbody without changing gravity?
I feel as if this shouldn't be happening. But when I set the velocity of my rigidbody using a Vector3 like the following code is showing, it somehow messes up the gravity and the cube object starts floating down really slowly.
rb.velocity = Vector3(xmove, rb.velocity.y, zmove);
Surely this shouldn't change the vertical velocity of the Ridgidbody at all, but it still does.
#pragma strict
var speed: float;
private var xvel: float;
private var zvel: float;
private var rb: Rigidbody;
function Start () {
rb = GetComponent.<Rigidbody>();
}
function FixedUpdate () {
xvel = Input.GetAxis("Horizontal");
zvel = Input.GetAxis("Vertical");
rb.velocity = Vector3(xvel * speed, rb.velocity.y, zvel * speed);
}
That's the full code attached to the player.
The reason I'm not using forces is because I want the player to be more responsive in its movement.
Answer by AlwaysSunny · Jul 09, 2015 at 12:41 PM
"Surely this shouldn't change the vertical velocity of the Ridgidbody at all"
That's precisely the point. It doesn't change the Y velocity - this code nullifies the acceleration due to gravity.
Gravity represents an acceleration, which is a change in velocity. You are specifically telling Unity to ignore that change by setting the Y velocity to be the same as it was before.
Writing to velocity should be considered an intermediate concept, because it fundamentally changes how you're interacting with the simulation, and all other bodies that interact with this one will be affected by your non-simulated changes.
First, ask yourself whether a velocity change is what you really need. Next, consider utilizing the AddForce overload which takes a ForceMode argument, and choose the "velocity change" mode.
Otherwise, the most physically appropriate way to directly write to velocity is to add to it - not set it.
How much you'll add will need to depend upon some kind of constraints you'll design. For instance, taking the dot product of the input vector and the current velocity will tell you whether you should allow additional meters-per-second to be added in that direction. This approach would circumvent this particular issue.
This is a fairly advanced concept, so let's pretend you don't want to get into that right now, and you just want to move forward with what you've got.
In that case, you can determine what the current frame's Y velocity should be using a kinematic equation. Use the current Y velocity as your initial velocity, the object's mass as the mass, and Physics.gravity.y as the acceleration. http://www.physicsclassroom.com/class/1DKin/Lesson-6/Kinematic-Equations
Thanks for the answer. I can see that I need a bit more knowledge on physics. Is there another way to create more responsive movement? I've tried using every Force$$anonymous$$ode there is, but they didn't seem to make that much difference. I've tried Force$$anonymous$$ode.VelocityChange
, but it still seemed unresponsive.
Also, I'm assu$$anonymous$$g I'd use the kinematic equation vf = vi + a*t
? So, this would be: yvel = rb.velocity.y + Physics.gravity.y * Time.deltaTime
? Or is there another Time value?
Right on the money with the equation, with one thing in $$anonymous$$d: You should always add forces and manipulate the physics sim from inside FixedUpdate. Within FixedUpdate, asking for Time.deltaTime actually returns Time.fixedDeltaTime, which is equal to the project's physics timestep. Worth mentioning.
With regard to creating a responsive rigidbody controller: This is actually a far deeper topic than it first appears. To the player, responsiveness and satisfaction are more important than realism. Adapting how much force is applied (or velocity is changed) from moment to moment to deliver maximum responsiveness is probably the biggest difference between a decent controller and an excellent controller.
There are lots of techniques to deliver maximum responsiveness and satisfaction, but it all boils down to how much force you add in a given frame. For instance, the dot-product technique mentioned in the answer is a good framework for a responsive controller. By comparing the current velocity to the requested force/change in velocity, you can make an informed decision about how that force/change is scaled.
Applying more force when the requested change is opposite the current velocity will enable you to stop and change direction quickly. Likewise, once you reach a certain "soft threshold" of velocity magnitude, requests for additional velocity in that direction should be dampened to keep the velocity within a certain sensible range.
Hopefully this all makes sense; it's not really that complicated, but it does take some planning and some understanding of what makes a controller fun.
Regarding the different force modes, I don't have much familiarity with the velocity change mode, but definitely read the documentation on the different modes. It's been like 18 months since I've done anything with physics. Totally looking forward to being done with my current project so I can get back to it! ;)
Your answer
Follow this Question
Related Questions
Rigidbody velocity disables gravity 1 Answer
Gravitational Object Creation for 3D Game 1 Answer
Apply Gravity to Car Physics 0 Answers
Modifying Gravity for Local Player 1 Answer
Rigidbody - Applying One-Time Force? Not Constant Force 2 Answers