Another ball movement question

hi coders,

After watching 25 videos, following 45 tutorials and reading a quadrillion forum post, i’m THAT close to give it up!

i’m gonna try to explain my problem in the best way. i’m making a 3d ball game.
to make things simple i have a plane and a ball. i have a simple movement script attached to the ball.

public class PlayerMovement : MonoBehaviour
{
    private Rigidbody rb;
    
    public float speed = 5.0f;

    // Start is called before the first frame update
    void Start()
    {
        rb = GetComponent<Rigidbody>();
    }

    // Update is called once per frame
    void Update()
    {
        
    }

    void FixedUpdate()
    {
        float moveHorizontal = Input.GetAxis("Horizontal");
        float moveVertical = Input.GetAxis("Vertical");

        Vector3 movement = new Vector3(moveHorizontal, 0.0f, moveVertical);

        rb.AddForce(movement * speed);
    }
}

now, my ball is moving forward, backwards, left and right. so far so good, but when my ball takes a corner to the left or right, i have to keep pressing left or right arrow to keep following the level. and that’s the problem here. the ball must follow it when i press the up arrow.
i think it has something to do with local or global?
oh and sorry for my bad english, i hope you understand the question :slight_smile:

AddForce simply adds a force every fixed update. Since you haven’t specified ForceMode ( Unity - Scripting API: Rigidbody.AddForce ) the velocity on the ball will remain constant when you stop pressing the keys. It will not accelerate but it will not decelerate either, assuming you don’t use Physics Materials and the level is flat.

From the documentation:
ForceMode.Force: Interprets the input as force (measured in Newtons), and changes the velocity by the value of force * DT / mass. The effect depends on the simulation step length and the mass of the body. Meaning: Stopping applying force will not change the velocity. It will simply cut the acceleration, so the velocity won’t increase. It won’t decrease either, if there is no force (ie. friction) applying a force opposite to the current velocity.

Quickest solution would be to assign Physics materials to the level ground and the ball. If you do this, ball will gradually slow down when you stop pressing the keys. Also with some proper calculations, AddForce will feel more like a car and less like a rocket.

OK, trying to understand…

What’s happening to the camera? Do you want it to face the way the ball is going at all times? That would make sense if you want the up arrow key to always go forwards, which I think you are saying…

Right now, you’re directing the ball based on the inputs provided to your “movement” Vector3 via your “moveVertical” and “moveHorizontal” floats.

Now, that’s not wrong at all, but there’s another key element you need to take into consideration here. The camera.

Now, you could just adapt the orientation using something like Camera.main.transform.TransformDirection(movement) but that isn’t actually right/complete and would shove the ball toward the ground if the camera’s not perfectly level.

First, you’ll need to get proper orientations for your forward and sideways movement relative to the camera, and to do that, you need one absolute variable to work with. A simple, common example of this is gravity. Since the default gravity vector points straight down, for example (0, -9.81, 0), you can count on it with respect to keeping your camera-relative controls “upright”. Because your input should generally be perpendicular to gravity, it’s a reliable vector to work with, when applicable.

// Example/simplifying text for this answer
Transform camT = Camera.main.transform;

Vector3 camForward = Vector3.Cross(camT.right, -physics.Gravity);
Vector3 camRight = Vector3.Cross(-physics.Gravity, camForward);

Vector3 movement = camRight * Input.GetAxis("Horizontal") + camForward * Input.GetAxis("Vertical");

Since you can’t absolutely count on the camera’s “forward” or “right” vectors always being perfectly perpendicular to gravity, you recalculate them as the “camForward” and "camRight’ vectors in my example.

ok last example, do you know the unity microgame kart? mario kart? gran turismo?
now, replace the kart or car with a ball. forward movement is always forward movement, no matter how many corners i take. no matter where in the level i am.