Adding Crouching to FPS Player in Unity

Adding a crouching mechanism can deepen immersion and provide tactical depth to gameplay, especially in first-person and stealth-based games. Building upon our Unity FPS Controller tutorial, this guide showcases how to add a smooth crouching feature in Unity.

Prerequisites

  • Basic familiarity with the Unity interface.
  • Understanding of the Unity 'CharacterController'.
  • The FPS controller script from the Unity FPS Controller tutorial.

Steps

  • In the class named 'SC_FPSController', from the Unity FPS Controller tutorial, add the following variables to handle crouching:
public bool isCrouching = false;
public float crouchHeight = 0.5f;
public float crouchSpeed = 3.5f;
public float crouchTransitionSpeed = 10f;
private float originalHeight;
public float crouchCameraOffset = -0.5f;
private Vector3 cameraStandPosition;
private Vector3 cameraCrouchPosition;
  • Modify the 'Start()' method to store the original height of the 'CharacterController' and set camera positions:
void Start()
{
    characterController = GetComponent<CharacterController>();
    originalHeight = characterController.height;

    // Define camera positions for standing and crouching
    cameraStandPosition = playerCamera.transform.localPosition;
    cameraCrouchPosition = cameraStandPosition + new Vector3(0, crouchCameraOffset, 0);

    // Lock cursor
    Cursor.lockState = CursorLockMode.Locked;
    Cursor.visible = false;
}
  • In the 'Update()' method, check for the crouch key press and toggle the 'isCrouching' variable:
if (Input.GetKeyDown(KeyCode.C) && canMove)
{
    isCrouching = !isCrouching;

    if (isCrouching)
    {
        characterController.height = crouchHeight;
        walkingSpeed = crouchSpeed;
    }
    else
    {
        characterController.height = originalHeight;
        walkingSpeed = 7.5f;
    }
}
  • Outside the previous block, implement the smooth transition for the camera's position between crouching and standing:
if (isCrouching)
{
    playerCamera.transform.localPosition = Vector3.Lerp(playerCamera.transform.localPosition, cameraCrouchPosition, crouchTransitionSpeed * Time.deltaTime);
}
else
{
    playerCamera.transform.localPosition = Vector3.Lerp(playerCamera.transform.localPosition, cameraStandPosition, crouchTransitionSpeed * Time.deltaTime);
}
  • Adjust the player's movement speed based on the current state:
float curSpeedX = canMove ? (isRunning ? runningSpeed : (isCrouching ? crouchSpeed : walkingSpeed)) * Input.GetAxis("Vertical") : 0;
float curSpeedY = canMove ? (isRunning ? runningSpeed : (isCrouching ? crouchSpeed : walkingSpeed)) * Input.GetAxis("Horizontal") : 0;

Questions:

  1. Why use 'Vector3.Lerp()' for camera transition during crouching?: The 'Vector3.Lerp()' function is utilized to interpolate smoothly between two vectors. In this context, it allows the camera to transition fluidly between standing and crouching positions rather than snapping abruptly.
  2. What's the role of 'crouchTransitionSpeed'?: The 'crouchTransitionSpeed' determines how quickly the transition between the crouching and standing camera positions takes place. A higher value results in a faster transition.
  3. Is it possible to customize the crouch key?: Absolutely. The crouch key is currently set to 'C' ('KeyCode.C'). Replace it with any desired 'KeyCode' to adjust the crouching key.

Conclusion

Incorporating a smooth crouching mechanic in Unity, which involves adjusting both the collider size and camera position, can significantly elevate player immersion. This guide has provided a method to achieve this with a natural, fluid transition.

Suggested Articles
Player 3D and 2D Wall Jump Tutorial for Unity
Creating Player Movement in Unity
Unity FPS Controller
Top-Down Player Controller Tutorial for Unity
Adding Double Jump Support to a 2D Platformer Character Controller in Unity
Flashlight Tutorial for Unity
Rigidbody-based Planetary Player Controller for Unity