FPS controller

Hey, so I’m pretty new to programming, and I really want to get good. I’m making an FPS right now, and I looked at a tutorial on how to do the movement with the camera etc, and got it working just fine. However, I don’t -understand- the code. I’ve programmed player movement and camera movement before, but I then used GetButton and lots of if-statements. Here they used GetAxis and the character controller and vectors. I don’t fully understand it. So, I would really, really appreciate it if someone could “translate” the code line by line, so that I actually learn and can do this again in the future. It’s pretty much just the GetAxis and Character controller I don’t understand. And I don’t fully grasp all the different variables, but I kinda get it. Super duper thanks in advance!

using UnityEngine;
using System.Collections;

public class FirstPersonController : MonoBehaviour {

    float movementSpeed = 5.0f;
    float mouseSensitivity = 2.0f;
    float verticalRotation = 0;
    public float upDownRange = 60.0f;

    // Use this for initialization
    void Start () {
    }
   
    // Update is called once per frame
    void Update () {

        //side rotation
        float rotSides = Input.GetAxis("Mouse X") * mouseSensitivity;
        transform.Rotate (0, rotSides, 0);

        //up/down rotation
        verticalRotation -= Input.GetAxis("Mouse Y") * mouseSensitivity;
        verticalRotation = Mathf.Clamp(verticalRotation, -upDownRange, upDownRange);
        Camera.main.transform.localRotation = Quaternion.Euler(verticalRotation, 0, 0);

        // movement
        float forwardSpeed = Input.GetAxis("Vertical") * movementSpeed;
        float sideSpeed = Input.GetAxis("Horizontal") * movementSpeed;

        Vector3 speed = new Vector3 (sideSpeed, 0, forwardSpeed);
        speed = transform.rotation * speed;

        CharacterController cc = GetComponent<CharacterController>();
        cc.Move(speed * Time.deltaTime);
    }
}

The Vertical and Horizontal axes are, by default, mapped to the WASD keys so for keyboard control they are essentially identical to calling GetButton. What the axes give you is controller/joystick support as well.

The variable “speed” is actually a little misleading since it really represents direction, not a speed. So - GetAxis when mapped to keyboard buttons will return either a 0, 1, or -1. 0 means no key is being pressed; 1 means forward in the context of Horizontal and right (I think!) for Vertical; and -1 means back and left (again, I think!). So it encapsulates all the logic of - am I going forward or back or left or right into into two lines instead of a big set of if-else statements.

Next, a Vector3 representing the direction the player is telling the avatar to move is constructed using the input values derived previously. That vector is then multiplied by the rotation of the avatar, which might seem weird but it’s actually “rotating” the vector so that the direction is relative to the facing of the avatar. If you didn’t do this then the avatar would always move in world space. Lastly, the avatar is moved via the CharacterController component.

1 Like

Alright, thank you! But when you say that the variable “speed” is misleading, do you mean the Vector3 on line 31, or do you mean all variables called something with speed? Like movementSpeed, forwardSpeed, sideSpeed, and speed.

And just a few things that I still don’t understand:

What does this line do? I get that it has to do with the cameras position, but I’ve never used localRotation or the Euler-thing
Camera.main.transform.localRotation=Quaternion.Euler(verticalRotation, 0, 0);

Here, what exactly does this do? What I (think I) understand is that we create a Vector3 called speed, and it’s a new Vector3, but what are the inputs and what does this Vector3 actually DO?

Vector3 speed = new Vector3 (sideSpeed, 0, forwardSpeed);
speed = transform.rotation * speed;

I meant the vector called speed.

Camera.main.transform.localRotation=Quaternion.Euler(verticalRotation, 0, 0);

Sets the camera’s rotation on the X axis equal to how much the player is manipulating the Mouse Y axis. This is basically a “look up and down”.

Vector3 speed = new Vector3 (sideSpeed, 0, forwardSpeed);
speed = transform.rotation * speed;

I already explained this previously. It makes a direction vector based on player input and then rotates that vector using the avatar’s rotation so that it’s “local” to the avatar. IE - if I press W then that vector is (0, 0, 1). If I move the avatar using that direction then he’ll move forward 1 unit along the blue Z axis in the editor. That works great when the avatar has no rotation and is facing in that direction but if I turn him then he won’t move in the direction he’s facing. Multiplying the rotation by the vector rotates that vector so he’ll move forward regardless of which direction he’s facing.