Creating an FPS controller using New Input System in Unity

There are tons of tutorial on creating an FPS controller using the old input system but very few when it comes to the new input system. So, in this tutorial, we will see how to use the Unity’s new input system to create an FPS controller for your game.

Video Tutorial

Add the player to the scene

  • Go to the Hierarchy window and create an empty game object called Player.
  • Add a 3D plane and name it as ground.
  • Add a Capsule as a child to Player and call it Player Body.
  • Rename the Main camera as Player view and set the position to where you want the head of the player. Do not set the camera as a child of the Player as we will be using a Rigidbody for the player.
FPS player

Adding the New Input System Package

Go to Window >Package Manager (Unity Registry) and install the Input System.

Click Yes on the pop up and this will restart your Unity Editor. Now the old input system is disabled and the new input system controls are added.

Unity Package Manager

Creating our FPS Input Action

  • Go to the Project window>Right click>Create>Input Action.
  • Let’s name it FPS_control.
  • Double click on the input action to open the Input action editor. Check on the Auto save check box on the top.
  • Create a new Action map by clicking on the + sign in the Action Maps tab and name it as Player_Map
  • Go to the Actions tab and create a new action called Movement.
  • Delete any existing bindings inside the Movement action. Then Click on the + sign on Movement action and select left/right/up/down composite or 2D vector composite.
  • Select the Up binding and click on Path variable in the Binding Properties tab. Click on the Listen button on the popup and press the W key on the keyboard.
  • Repeat the step for Down, Left and Right bindings

We don’t need to set up the action map for mouse look as we can directly get it with a single line of code. But if you are planning to use a gamepad to look around then you need to set up an action map for that.

Unity Black Friday Deals

Input action Editor

Select the Input action FPS_control in the project window and go to the inspector window. Check Generate C# Class. This will create a new C# script with the same name as out Input Action.

Now we can reference this class to access the actions.

Creating the Mouse look script

When the mouse moves left and right, we need to rotate the camera along the Y axis and if the mouse moves Up and down then we need to rotate the camera around the X axis.

Also, the player needs to be rotated around the Y axis when the mouse movement is in the horizontal axis.

Also, we need to update the mouse position to the player position.

You can get the Mouse movement using the “Mouse.current.delta.ReadValue()” in the new input system.

using UnityEngine;
using UnityEngine.InputSystem;

public class Look_Control : MonoBehaviour
{
    public GameObject Player;
    float xrotation;
    float yrotation;
    Vector2 mousemovement;
    float camera_y;
    Vector3 pos;
    public float mouse_sensitivity=10f;

    void Start()
    {
        camera_y=transform.position.y-Player.transform.position.y;
        Cursor.lockState=CursorLockMode.Locked;
    }
    

    // Update is called once per frame
    void Update()
    {
        //Update Mouse position to player position
        pos=Player.transform.position;
        pos.y+=camera_y;
        transform.position=pos;
        //Get mouse movement in new input system
        mousemovement=Mouse.current.delta.ReadValue();     
        xrotation-=mousemovement.y*Time.deltaTime*mouse_sensitivity;   
        xrotation=Mathf.Clamp(xrotation,-90,90);
        yrotation+=mousemovement.x*Time.deltaTime*mouse_sensitivity;
        transform.rotation=Quaternion.Euler(xrotation,yrotation,0);
        //Rotating the player
        Player.transform.localRotation=Quaternion.Euler(0,yrotation,0);
        
    }
}

Assign the player game object to the Look_Control script. Now you should be able to look around by moving the mouse. If you feel that the axis is inverted then change the “+” sign to “-” in the xrotation and yrotation variables.

Getting the Player to move

We will be using the new Input action to move the player. First let’s add a Rigidbody component to the Player game object. Create a new script called Player_controller and attach it to the Player.

This script will move the player with physics forces. We need to add a jump Action to out input system. So, open up the FPS_control input system and add a new action jump. Let the action type be button and add the binding to Space key

Jump Action
Here is the final script that you can attach to your player
using UnityEngine;

public class Player_Controller : MonoBehaviour
{
    public GameObject ground;
    FPS_control input_control;
    Vector2 move;
    float movement_force=50000;
    Rigidbody rb;
    bool isgrounded=true;
    float jumpforce=500;
    // Start is called before the first frame update
    void Start()
    {
        input_control=new FPS_control();
        input_control.Player_Map.Enable();
        rb=GetComponent<Rigidbody>();
        move=Vector2.zero;
    }

    // Update is called once per frame
    void FixedUpdate()
    {
       groundcheck();
       playermove();
       if(isgrounded && input_control.Player_Map.Jump.ReadValue<float>()>0)
       {
         Playerjump();
       } 

       

    }
    void groundcheck()
    {
         if(transform.position.y-ground.transform.position.y>1.5)
        {
            isgrounded=false;

            rb.drag=0.1f;
        }
        else{
            isgrounded=true;
            rb.drag=3f;
        }

    }
    void playermove()
    {
        move=input_control.Player_Map.Movement.ReadValue<Vector2>();
        float forcez=move.x*movement_force*Time.deltaTime;    
        float forcex=move.y*movement_force*Time.deltaTime;    
        rb.AddForce(transform.forward*forcex,ForceMode.Force);
        rb.AddForce(transform.right*forcez,ForceMode.Force);

    }
    void Playerjump()
    {
       rb.AddForce(Vector3.up*jumpforce,ForceMode.Impulse); 
    }
}

Make sure you add the ground to the Player_controller. If your player is not jumping then check the offset value.

Few more things to try

  1. Set the y velocity of the player to zero when its grounded. That way the player will jump the same height every time.
  2. Use Raycast to check if the player is grounded.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.