As you’ve said, what your code does is it moves the object in global axes. To make the movement local, you can multiply your input with your player’s Transform’s local axes. An example that does this could be:
float moveLR = Input.GetAxis("Horizontal") * speed;
float moveFB = Input.GetAxis("Vertical") * speed;
Vector3 movement = moveLR * transform.right + moveFB * transform.forward;
transform.position += movement * Time.deltaTime;
Up on this, I see that your player already has a RigidBody attached. If you’d like, instead of directly modifying the player’s position, you could command the RigidBody to 1. This would ensure that your movement is done within the laws of physics. Also, your player would be a lot smoother when it comes to interacting with other objects. To achieve this, you could use:
private void FixedUpdate()
{
rb.MovePosition(rb.position + movement * Time.fixedDeltaTime);
}
Generally, whenever you’re dealing with physics, you would want to do it in the FixedUpdate. This also applies to your jumping mechanism. Also get it into the FixedUpdate. And lastly, if you’d like to have a jumping mechanism that works instantly, you should be passing a ForceMode suitable for that. The default ForceMode is designed for continuous forces. I don’t know what you exactly want, but I guess ForceMode.VelocityChange could suit your needs. So your code would roughly look like this, you can fill in the details:
private Rigidbody rb;
[SerializeField]
private float jumpHeight = 10f;
private Vector3 movement = Vector3.zero;
private float verticalVelocity = 0;
private void Update()
{
float moveLR = Input.GetAxis("Horizontal") * speed;
float moveFB = Input.GetAxis("Vertical") * speed;
movement = moveLR * transform.right + moveFB * transform.forward;
if(Input.GetKeyDown(KeyCode.Space) && isGrounded)
{
verticalVelocity = jumpHeight;
}
else
{
verticalVelocity = 0f;
}
}
private void FixedUpdate()
{
if(movement != Vector3.zero)
{
rb.MovePosition(rb.position + movement * Time.fixedDeltaTime);
}
if(verticalVelocity != 0)
{
rb.AddForce(0f, jumpHeight, 0f, ForceMode.VelocityChange);
}
}
In programming, you should always choose the least accessible access modifier that only does what you want, hence I changed some of yours. The SerializeField attribute in this case, still lets you edit your variables from inside the Unity Editor; but it cuts the access from outside the PlayerMovement class, which I assumed is unnecessary. With the HideInInspector attribute, you can do the opposite; this attribute lets your fields be public with the prevention of editing in the Unity Editor.