Help getting a rigidbody sphere rolling in 8 directions

Hello there! This is my first post, so go easy on me.
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

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!

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