This script is attached to Player object:

using UnityEngine;
using System.Collections;

[RequireComponent (typeof (Rigidbody))]
[RequireComponent (typeof (BoxCollider))]

public class PlayerController : MonoBehaviour {

    public float walkSpeed = 6;
    public float runSpeed = 10;
    public float strafeSpeed = 5;
    public float gravity = 20;
    public float jumpHeight = 2;
    public bool canJump = true;
    private bool isRunning = false;
    private bool isGrounded = false;

    public bool IsRunning
        get { return isRunning; }

    void Awake () {
        GetComponent<Rigidbody>().freezeRotation = true;
        GetComponent<Rigidbody>().useGravity = false;

    void FixedUpdate () {
        // get correct speed
        float forwardAndBackSpeed = walkSpeed;

        // if running, set run speed
        if (isRunning) {
            forwardAndBackSpeed = runSpeed;

        // calculate how fast it should be moving
        Vector3 targetVelocity = new Vector3(Input.GetAxis("Horizontal") * strafeSpeed, 0, Input.GetAxis("Vertical") * forwardAndBackSpeed);
        targetVelocity = transform.TransformDirection(targetVelocity);

        // apply a force that attempts to reach our target velocity
        Vector3 velocity = GetComponent<Rigidbody>().velocity;
        Vector3 velocityChange = (targetVelocity - velocity);
        velocityChange.y = 0;
        GetComponent<Rigidbody>().AddForce(velocityChange, ForceMode.VelocityChange);

        // jump
        if (canJump && isGrounded && Input.GetButton("Jump")) {
            GetComponent<Rigidbody>().velocity = new Vector3(velocity.x, Mathf.Sqrt(2 * jumpHeight * gravity), velocity.z);
            isGrounded = false;

        // apply gravity
        GetComponent<Rigidbody>().AddForce(new Vector3 (0, -gravity * GetComponent<Rigidbody>().mass, 0));

    void Update() {
        // check if the player is touching a surface below them

        // check if the player is running
        if (isGrounded && Input.GetButtonDown("Sprint")) {
            isRunning = true;

        // check if the player stops running
        if (Input.GetButtonUp("Sprint")) {
            isRunning = false;

    void checkGrounded() {
        /* ==============
         * REMEMBER
         * ==============
         * If you change the size of the prefab, you may have
         * to change the length of the ray to ensure it hits
         * the ground.
         * All obstacles/walls/floors must have rigidbodies
         * attached to them. If not, Unity physics may get
         * confused and the player can jump really high
         * when in a corner between 2 walls for example.
        float rayLength = 0.7f;
        RaycastHit hit;
        Ray ray = new Ray(transform.position, -transform.up);
        //Debug.DrawRay(ray.origin, ray.direction * rayLength);
        // if there is something directly below the player
        if (Physics.Raycast(ray, out hit, rayLength)) {
            isGrounded = true;
There are some parts in the script it's using "Sprint" For example:

// check if the player is running
        if (isGrounded && Input.GetButtonDown("Sprint")) {
            isRunning = true;

        // check if the player stops running
        if (Input.GetButtonUp("Sprint")) {
            isRunning = false;

But "Sprint" is not defined in the editor input: Edit > Project Settings > Input:

Input Manager

I can change the size in the Input Manager to 19 and it will duplicate the Cancel so I changed the name to Sprint. But what should be the config for the Sprint ? It's now the Cancel config. Config I mean the settings for each property.

Input Manager with Sprint but settings of Cancel

When running the game before added the Sprint I'm getting this exception:

ArgumentException: Input Button Sprint is not setup. To change the input settings use: Edit -> Project Settings -> Input PlayerController.Update () (at Assets/My Scripts/Character1/PlayerController.cs:62)

My question is what settings should I set for the Sprint in the Input Manager ?

  • \$\begingroup\$ Well, you tell us: what controls would you like the player to use to perform a sprint action? \$\endgroup\$
    – DMGregory
    May 14 '18 at 20:56
  • \$\begingroup\$ @DMGregory The keys (left)Shift + W \$\endgroup\$ May 14 '18 at 21:33

I'm not sure you can use key combinations as input, so you may need to set up two buttons and then check for a GetButton on the shift during a GetButtonDown on the W.

Input manager configuration:

  Positive Button: w
  Positive Button: left shift
  Alt Positive Button: right shift

That will allow either shift to be used. If you don't want that, leave the Alt Positive Button blank. Negative buttons and other alt buttons can be left blank. All the other settings should be fine.

Then your code would look something like this:

if (isGrounded && Input.GetButton("Shift") && Input.GetButtonDown("Sprint")) {
    isRunning = true;

if (Input.GetButtonUp("Shift") || Input.GetButtonUp("Sprint")) {
    isRunning = false;

Or, as @DMGregory pointed out, the code can be simplified to one line:

isRunning = isGrounded && Input.GetButton("Shift");

This has slightly different behavior, since it triggers when holding w first and then beginning to hold shift, whereas the first code example only triggers when you hold shift first. I don't know exactly what controls you want, but the second code example is probably better.


It turns out I was overthinking this. You already have W assigned to your Vertical axis, which you are using. Just have isRunning equal the state of the shift key.

//  Positive Button: left shift
//  Alt Positive Button: right shift

isRunning = GetButton("Sprint");
  • \$\begingroup\$ You can simplify the code example to isRunning = isGrounded && Input.GetButton("Sprint"); \$\endgroup\$
    – DMGregory
    May 14 '18 at 23:21
  • \$\begingroup\$ @DMGregory, good point. I was trying to make the change as minimal as possible, but I added some shorter code like what you posted that handles the order of key holds better. \$\endgroup\$
    – tyjkenn
    May 15 '18 at 1:01
  • \$\begingroup\$ Note here W is probably already mapped to the forward/"Vertical" input (as it is in the default settings), so it suffices to map the shift key to the Sprint toggle. \$\endgroup\$
    – DMGregory
    May 15 '18 at 2:21
  • \$\begingroup\$ @DMGregory, yeah ... In context of the rest of the code, I was overthinking this. \$\endgroup\$
    – tyjkenn
    May 15 '18 at 3:09

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .