1
votes

I created a FPS movement but the player's movement is wrong. When rotating to the left or right the player still moves forward.

PlayerMovement.cs

public class PlayerMovement : MonoBehaviour
{
    private Vector3 movement;
    private Rigidbody rigid;
    private bool jumpPressed;

    private const int MOVEMENT_SPEED = 8;
    private const int JUMP_POWER = 20;

    private void Awake()
    {
        rigid = GetComponent<Rigidbody>();
    }

    private void Update()
    {
        SetInputs();
    }

    private void FixedUpdate()
    {
        Jump();
        Move();
    }

    private void SetInputs()
    {
        movement.x = Input.GetAxis("Horizontal") * MOVEMENT_SPEED;
        movement.y = rigid.velocity.y;
        movement.z = Input.GetAxis("Vertical") * MOVEMENT_SPEED;
        jumpPressed = Input.GetKeyDown(KeyCode.Space);
    }

    private void Jump()
    {
        if (jumpPressed && GroundCheck())
        {
            movement.y = JUMP_POWER;
            jumpPressed = false;
        }
    }

    private void Move()
    {
        rigid.velocity = movement;
    }

    private bool GroundCheck()
    {
        return true;
    }
}

CameraMovement.cs

public class CameraMovement : MonoBehaviour
{
    private Transform player;
    private Vector2 rotation;

    private Quaternion originalRotation;

    private const int HORIZONTAL_ROTATION_SPEED = 5;
    private const int VERTICAL_ROTATION_SPEED = 5;
    private const int VERTICAL_ROTATION_MIN = -80;
    private const int VERTICAL_ROTATION_MAX = 80;

    private void Awake()
    {
        player = GameObject.FindGameObjectWithTag("Player").transform;
    }

    private void Start()
    {
        originalRotation = transform.localRotation;
    }

    private void Update()
    {
        SetInputs();
        RotateCamera();
        RotatePlayer();
    }

    private void SetInputs()
    {
        rotation.x = Input.GetAxisRaw("Mouse X") * HORIZONTAL_ROTATION_SPEED;

        rotation.y += Input.GetAxisRaw("Mouse Y") * VERTICAL_ROTATION_SPEED;
        rotation.y = Mathf.Clamp(rotation.y, VERTICAL_ROTATION_MIN, VERTICAL_ROTATION_MAX);
    }

    private void RotateCamera()
    {
        Quaternion verticalRotation = Quaternion.AngleAxis(rotation.y, Vector3.left);
        transform.localRotation = originalRotation * verticalRotation;
    }

    private void RotatePlayer()
    {
        player.localRotation *= Quaternion.AngleAxis(rotation.x, player.up);
    }
}

I provide a small gif showing the wrong movement when rotating.

https://media.giphy.com/media/2jMy38g1PjckODc6B0/giphy.gif

When rotating the player by rotating the camera the player rotates correctly around his y-axis. Somehow he doesn't move forward to the direction he is facing, he just moves along one direction.

What needs to be fixed?

2

2 Answers

0
votes

I see your moving logic is not dealing with the camera facing direction, it just make the object moves with the input axis values, and that's why your object is moving like this.

If you want to make 'forward' axis means 'walking forward to my facing direction', you should combine the movement with the camera rotation.

You can try something like

rigid.velocity = Camera.main.transform.rotation * movement;

in your Move().

0
votes

this is reinventing the wheel. the unity standar asset package comes with a fps prefab that is customizable and works well. the script is robust, and the controls are elegant, with a little tweaking its easy to make it your own, save a little time, download the Unity Standard Asset package from the unity store, and use the firstperson char prefab. you will be pleased i think.