Understanding Player Movement in Unity with Character Controller
When developing a game in Unity, one of the fundamental aspects to master is player movement. Whether you're creating a first-person shooter, a platformer, or any other type of game, having precise control over how your player moves is essential for a smooth and enjoyable player experience. In this blog post, we'll delve into a Unity script called SCplayerMovement
that demonstrates a basic player movement setup using Unity's CharacterController component.
Player Movement Script Overview
The SCplayerMovement
script is designed to be attached to a player character in Unity. It provides basic functionality for moving the player character in response to player input, simulating gravity, and checking if the player is grounded. Let's break down the key components of this script.
Required Imports
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
These using statements allow us to access Unity's core functionalities.
Variables
public float _speed = 10f;
Transform _player;
CharacterController _character;
float _gravity = -9.81f;
Vector3 Velocity;
bool _isGrounded;Transform _groundCheck;
float _groundDistance = 0.2f;
LayerMask _groundMask;
_speed
: This public variable allows you to control the player's movement speed._player
: A reference to the player's transform._character
: A reference to the CharacterController component attached to the player._gravity
: The gravitational force applied to the player.Velocity
: A vector representing the player's current velocity._groundCheck
: The transform used to check if the player is grounded (often a child object)._groundDistance
: The distance used for ground checking._groundMask
: A LayerMask that specifies what is considered as ground._isGrounded
: A boolean flag indicating whether the player is grounded.
Initialization (Start Method)
void Start()
{
// Get the Transform component of the game object this script is attached to
_player = this.transform;
// Check if the player transform is null
if (_player == null)
{
Debug.LogError("Player is null");
}
// Get the CharacterController component attached to the player
_character = _player.GetComponent<CharacterController>();
// Check if the CharacterController is null
if (_character == null)
{
Debug.LogError("CharacterController is null");
}
// Get the Transform for ground checking (usually a child object)
_groundCheck = this.transform.GetChild(2).transform;
// Check if the groundCheck is null
if (_groundCheck == null)
{
Debug.LogError("Ground Check is null");
}
// Define the layer mask to specify what is considered as ground
_groundMask = LayerMask.GetMask("Ground");
}
In this section, we initialize our variables, such as _player
, _character
, and _groundCheck
, by getting the appropriate components or transforms from the GameObject to which this script is attached.
We also define the _groundMask
, which is a LayerMask used to identify ground objects in the scene. The script assumes that the "Ground" layer is used to tag ground objects.
Player Movement (FixedUpdate Method)
void FixedUpdate()
{
// Check if the player is grounded using a sphere cast
_isGrounded = Physics.CheckSphere(_groundCheck.position, _groundDistance, _groundMask);
// If grounded and falling, reset vertical velocity to a small negative value
if (_isGrounded && Velocity.y < 0f)
{
Velocity.y = -0.5f;
}
// Get player input for movement (WASD keys) in the X and Z axes
float Xaxis = Input.GetAxis("Horizontal");
float Zaxis = Input.GetAxis("Vertical");
// Create a movement vector based on player input
Vector3 move = _player.right * Xaxis + _player.forward * Zaxis;
// Apply movement to the player using CharacterController and adjust for frame rate
_character.Move(move * _speed * Time.deltaTime);
// Apply custom gravity to the player
Velocity.y += _gravity * Time.deltaTime * Time.deltaTime;
// Apply vertical velocity to the player's position
_character.Move(Velocity);
}
In this section, we update the _isGrounded
variable using Physics.CheckSphere
. This function checks if there is any ground beneath the player within the specified _groundDistance
.
If the player is grounded and falling (Velocity.y < 0f
), we reset the vertical velocity to a small negative value to prevent any jitters.
We then read player input for movement in the X and Z axes (typically from the WASD keys) and create a movement vector.
Using CharacterController.Move
, we apply the movement vector to the player's position. We adjust the movement based on the frame rate (Time.deltaTime
) to make it frame rate-independent.
Custom gravity is applied by modifying the Velocity
vector. This helps simulate realistic falling.
Finally, we apply the vertical velocity to the player's position using CharacterController.Move
.
IMPORTANT
- Create Player as an empty object and add Character controller on to it.
- Create a capsule (bean) 3D object inside the Player Object.
- Disable the capsule's collider as character controller acts as one so no need for two colliders.
- Create an empty object as GroundCheck and place it under the player object.
Conclusion
The SCplayerMovement
script provides a basic foundation for player movement in Unity using a CharacterController. It covers essential aspects such as player input, ground checking, and gravity simulation. You can build upon this script to add additional features like jumping, crouching, or more complex movement mechanics, depending on your game's requirements.
Understanding and mastering player movement is a crucial step in game development, and this script serves as a valuable starting point. With this knowledge, you can create more immersive and enjoyable player experiences in your Unity games.
Comments
Post a Comment