Help getting a rigidbody sphere rolling in 8 directions

Hello there! This is my first post, so go easy on me. :smile:
I’m trying to make a ball (sphere) to roll in all directions. I’ve currently written a script so I can get it moving north, south, west, and east but only one at a time. I want the player to be able to get the ball rolling e.g. southeast, northwest, etc… I’ve been looking all around, but maybe not the right places?
I really hope you guys can help me! Thank you :slight_smile:

Below is my code

public class Controller : MonoBehaviour
{
    Vector3 input;
    Rigidbody m_Rigidbody;
    public float m_Speed = 2.0f;
    private string direction;
    
    void Awake()
    {
        m_Rigidbody = GetComponent<Rigidbody>();
    }

    // Update is called once per frame
    void FixedUpdate()
    {
        GetInput();

        if (Mathf.Abs(input.x) < 1 && Mathf.Abs(input.y) < 1) return;
        {
            print(input);
            if (Input.GetKey(KeyCode.S))
            {
                m_Rigidbody.velocity = (Vector3.forward)  * (m_Speed * Time.deltaTime);
            }
            if (Input.GetKey(KeyCode.A))
            {
                m_Rigidbody.velocity = Vector3.right * (m_Speed * Time.deltaTime);
            }
            if (Input.GetKey(KeyCode.W))
            {
                m_Rigidbody.velocity = Vector3.back * (m_Speed * Time.deltaTime);
            }
            if (Input.GetKey(KeyCode.D))
            {
                m_Rigidbody.velocity = Vector3.left * (m_Speed * Time.deltaTime);
            }
        }
    }

    void GetInput()
    {
        input.x = Input.GetAxisRaw("Horizontal");
        input.y = Input.GetAxisRaw("Vertical");
    }
}

6127259–667904–Controller.cs (1.34 KB)

You’re just stomping over any previously set velocity. If you press S then you set the velocity but if you’re also press W then you set the velocity and overwrite the movement for S.

You should gather your input then calculate and set the velocity once.

Here’s a basic idea (not the most efficient and not tested but it’ll give you an idea):

var direction = Vector3.zero;

if (Input.GetKey(KeyCode.S))
{
    direction += Vector3.forward
}

if (Input.GetKey(KeyCode.A))
{
    direction += Vector3.right
}

if (Input.GetKey(KeyCode.W))
{
    direction += Vector3.back
}

if (Input.GetKey(KeyCode.D))
{
    direction += Vector3.left
}

m_Rigidbody.velocity = direction.normalized * m_Speed * Time.fixedDeltaTime;

Also note that you need to be careful when reading input during the fixed-update as you can miss certain types of input such as input that checks if something happened “this frame”. FixedUpdate isn’t per-frame.

1 Like

Alright, I will test your solution and get back to you whether it’s working, but I understand the overall idea so thank you regardless! :smile:

1 Like

Good lord, it works. Thank you so much! If you don’t mind me asking, how do you like the solution of constant if-statements? Is there a better and less clumsy way of checking for user input?

Switch statements, maybe?

https://learn.unity.com/project/c-survival-guide-switch-statements