I have my character with a rigidbody and attracted by the planet. I am trying to move it with its velocity. I tried this script:

    Vector3 x = Input.GetAxis("Horizontal")*transform.right*speed;
    Vector3 z = Input.GetAxis("Vertical")*transform.forward*speed;
    rb.velocity = new Vector3(x.x + z.x,rb.velocity.y,x.z+z.z);
    rb.AddForce(-transform.up * GravityForce);

and I have also tried with transform.TransformDirection but the result is the same. Everything goes well until I get to the middle of the planet, then my character stop going forward. Also, it sometimes stop sticking to the planet as if my character sometimes start going straight instead of going straight relative to its rotation around the planet.

  • \$\begingroup\$ Your code assumes that gravity always acts along the global y axis, which is - by definition - not the case on a spherical planet. \$\endgroup\$
    – DMGregory
    Commented Sep 4, 2021 at 2:39
  • \$\begingroup\$ What do you mean ? Isn't -transform.up applying the force toward where is "down" for the player based on its rotation ? \$\endgroup\$ Commented Sep 4, 2021 at 3:39
  • \$\begingroup\$ Look at your velocity code one line above. It applies the input to global x and z alone, leaving only global y in freefall, regardless of how your object is oriented. \$\endgroup\$
    – DMGregory
    Commented Sep 4, 2021 at 10:37
  • \$\begingroup\$ How can I pally to this? \$\endgroup\$ Commented Sep 4, 2021 at 12:15

1 Answer 1


As mentioned in the comments, this line:

rb.velocity = new Vector3(x.x + z.x,rb.velocity.y,x.z+z.z);

...always replaces the global x and z components of your velocity with this frame's input, so gravity can only ever accumulate freely on the global y axis, and player input in the direction facing global y is discarded.

It looks like you meant to do something like this, capturing the amount of velocity parallel to the character's y axis, and passing that through unchanged, while applying input parallel to the character's x and z axes.

float verticalSpeed = Vector3.Dot(transform.up, rb.velocity);

rb.velocity = transform.right   * Input.GetAxis("Horizontal") * speed
            + transform.up      * verticalSpeed
            + transform.forward * Input.GetAxis("Vertical")   * speed;

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .