# Controlling a Character

A `Character` encompasses a collection of methods designed to facilitate action execution. For instance, the `SetMovementDirection` method prompts the character to move in a specified direction (in world space).&#x20;

Similarly, the `Jump` method initiates a jump, while the `StopJumping` method halts the ongoing jump—particularly crucial when a variable jump height is in use.

&#x20;Likewise, the `Crouch` method is utilized to initiate the character's crouching action, and the `UnCrouch` method is employed to cease the crouching state.

These actions can be managed using a custom character class through inheritance, through an external script or visual scripting solution, as preferred.

## Custom Character

This example demonstrates how to control a player derived from the `Character` class:

```csharp
/// <summary>
/// This example shows how to extend a Character (through inheritance)
/// adding input management.
/// </summary>

public class PlayerCharacter : Character
{
    private void Update()
    {
        // Movement input
        
        Vector2 inputMove = new Vector2()
        {
            x = Input.GetAxisRaw("Horizontal"),
            y = Input.GetAxisRaw("Vertical")
        };
        
        Vector3 movementDirection =  Vector3.zero;

        movementDirection += Vector3.right * inputMove.x;
        movementDirection += Vector3.forward * inputMove.y;
        
        // If character has a camera assigned...
        
        if (camera)
        {
            // Make movement direction relative to its camera view direction
            
            movementDirection = movementDirection.relativeTo(cameraTransform);
        }

        SetMovementDirection(movementDirection);
        
        // Crouch input
        
        if (Input.GetKeyDown(KeyCode.LeftControl) || Input.GetKeyDown(KeyCode.C))
            Crouch();
        else if (Input.GetKeyUp(KeyCode.LeftControl) || Input.GetKeyUp(KeyCode.C))
            UnCrouch();
        
        // Jump input
        
        if (Input.GetButtonDown("Jump"))
            Jump();
        else if (Input.GetButtonUp("Jump"))
            StopJumping();
    }
}
```

## Controlling a Character

The following example illustrates how to control a character from an external 'entity,' specifically the `CharacterInput` script:

```csharp
using UnityEngine;
using ECM2;

public class CharacterInput : MonoBehaviour
{
    // The controlled Character
    
    private Character _character;

    private void Awake()
    {
        // Cache controlled character
        
        _character = GetComponent<Character>();
    }

    private void Update()
    {
        // Poll movement input
        
        Vector2 inputMove = new Vector2()
        {
            x = Input.GetAxisRaw("Horizontal"),
            y = Input.GetAxisRaw("Vertical")
        };
        
        // Compose a movement direction vector in world space
        
        Vector3 movementDirection =  Vector3.zero;

        movementDirection += Vector3.right * inputMove.x;
        movementDirection += Vector3.forward * inputMove.y;
        
        // If character has a camera assigned,
        // make movement direction relative to this camera view direction
        
        if (_character.camera)
        {               
            movementDirection 
                = movementDirection.relativeTo(_character.cameraTransform);
        }
        
        // Set character's movement direction vector

        _character.SetMovementDirection(movementDirection);
        
        // Crouch input
        
        if (Input.GetKeyDown(KeyCode.LeftControl) || Input.GetKeyDown(KeyCode.C))
            _character.Crouch();
        else if (Input.GetKeyUp(KeyCode.LeftControl) || Input.GetKeyUp(KeyCode.C))
            _character.UnCrouch();
        
        // Jump input
        
        if (Input.GetButtonDown("Jump"))
            _character.Jump();
        else if (Input.GetButtonUp("Jump"))
            _character.StopJumping();
    }
}
```

Finally, add the newly created `CharacterInput`  script to your  **Character** GameObject. You should be able to **move**, **jump** and **crouch**!

{% hint style="warning" %}
**Crouching** and **Uncrouching** solely manipulate the character's capsule collider, without influencing the visual representation of your character.
{% endhint %}

## Using Input System

The following example shows how to control a character using the [`InputSystem`](https://docs.unity3d.com/Packages/com.unity.inputsystem@1.7/manual/index.html). In this case, we'll utilize the [`PlayerInput`](https://docs.unity3d.com/Packages/com.unity.inputsystem@1.7/manual/PlayerInput.html) component, which streamlines the setup and management of input controls.

The `PlayerInput` component efficiently handles input actions, taking care of initialization, de-initialization, input processing, event triggering, and more. Consequently, our main task involves simply creating event handlers for our actions, a process reminiscent of the old input manager.

```csharp
using ECM2;
using UnityEngine;
using UnityEngine.InputSystem;

public class CharacterInput : MonoBehaviour
{
    // Cached controlled character
        
    private Character _character;
    
    /// <summary>
    /// Movement InputAction event handler.
    /// </summary>

    public void OnMove(InputAction.CallbackContext context)
    {
        // Read input values

        Vector2 inputMovement = context.ReadValue<Vector2>();

        // Compose a movement direction vector in world space

        Vector3 movementDirection = Vector3.zero;

        movementDirection += Vector3.forward * inputMovement.y;
        movementDirection += Vector3.right * inputMovement.x;

        // If character has a camera assigned,
        // make movement direction relative to this camera view direction

        if (_character.camera)
        {               
            movementDirection 
                = movementDirection.relativeTo(_character.cameraTransform);
        }
    
        // Set character's movement direction vector

        _character.SetMovementDirection(movementDirection);
    }

    /// <summary>
    /// Jump InputAction event handler.
    /// </summary>

    public void OnJump(InputAction.CallbackContext context)
    {
        if (context.started)
            _character.Jump();
        else if (context.canceled)
            _character.StopJumping();
    }

    /// <summary>
    /// Crouch InputAction event handler.
    /// </summary>

    public void OnCrouch(InputAction.CallbackContext context)
    {
        if (context.started)
            _character.Crouch();
        else if (context.canceled)
            _character.UnCrouch();
    }

    private void Awake()
    {
        //
        // Cache controlled character.
        
        _character = GetComponent<Character>();
    }
}
```

As you can see, the operation of the character closely resembles that of the old input manager (or any other input package), where we rely on the character's action methods to control it.

{% hint style="info" %}
Please refer to the [`PlayerInput`](https://docs.unity3d.com/Packages/com.unity.inputsystem@1.7/manual/PlayerInput.html) component documentation for more detailed information.
{% endhint %}
