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.

“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