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).
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.
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:
/// <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:
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!
Crouching and Uncrouching solely manipulate the character's capsule collider, without influencing the visual representation of your character.
Using Input System
The following example shows how to control a character using the InputSystem. In this case, we'll utilize the PlayerInput 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.
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.
Please refer to the PlayerInput component documentation for more detailed information.