If you want to create a 3D game, chances are you’ll need to build a character controller. A controller allows your characters to move and interact with the environment in your game. In this article, we will guide you through the process of creating a simple 3D character controller in Unity using C scripting.
Before we begin, make sure you have Unity installed on your computer. You can download it from their website: https://unity.com/download
Setting Up Your Scene
The first step is to set up your scene. Create a new project in Unity and open the “3D Object” window by clicking on “Window” in the menu bar, then selecting “3D Object”. From there, you can choose the type of object you want to add to your scene. For our character controller, we’ll use a cube.
Once you’ve added your cube to the scene, go ahead and position it in the center of the screen. You can also resize it by using the handles on the sides or top and bottom.
Next, we need to add some textures to our cube. Go to “Material” in the menu bar, then select “Create”. From there, you can choose a texture and apply it to your cube. We’ll use a simple red and blue checkered pattern for this example.
Creating the Character Controller
Now that our scene is set up, we can start building our character controller. First, we need to create a new C script in Unity by going to “Assets” in the menu bar, then selecting “Create”. From there, choose “C Script”.
Name your script “CharacterController” and double-click on it to open it in your preferred code editor.
The first thing we need to do is import the necessary namespaces at the top of our script:
csharp
using UnityEngine;
This will allow us to use Unity’s built-in classes and functions.
Next, we need to define some variables that will be used in our controller. These include:
csharp
public float moveSpeed 5f; // how fast the character moves
public float jumpForce 10f; // how high the character jumps
public Transform groundCheck; // where the character checks for a ground surface
public LayerMask groundLayer; // which layers are considered ground
We’ll also need to create some public variables for our character’s movement and jumping animations:
csharp
[SerializeField] Animator anim; // reference to the character’s animator component
[SerializeField] Rigidbody rb; // reference to the character’s rigidbody component
public bool isGrounded; // whether the character is on the ground or not
Now we can start writing our controller’s code. We’ll start by checking if the character is on the ground:
csharp
void Update()
{
isGrounded Physics.OverlapCircle(groundCheck.position, 0.1f, groundLayer);
}
This uses Unity’s built-in `Physics.OverlapCircle` function to check if there is any object within a 0.1-unit radius of the character’s ground check position that belongs to the “ground” layer. If there is, we set `isGrounded` to true.
Next, we need to handle the character’s movement and jumping inputs:
csharp
void FixedUpdate()
{
float moveX Input.GetAxis("Horizontal") moveSpeed; // how fast the character moves
float moveY Input.GetAxis("Vertical") moveSpeed; // how fast the character moves
Vector3 targetVelocity new Vector3(moveX, rb.velocity.y, moveY); // calculate the target velocity for the character’s rigidbody component and set it accordingly
rb.velocity targetVelocity; // set the character’s velocity to the target velocity
if (Input.GetButtonDown("Jump") && isGrounded)
{
rb.AddForce(new Vector3(0f, jumpForce, 0f), ForceMode2D.Impulse); // add a force to the character’s rigidbody component in the upward direction and trigger the "Jump" animation
anim.SetTrigger("Jump"); // trigger the "Jump" animation
isGrounded false; // set isGrounded
to false so that the character can no longer jump after landing
}
}
Finally, we need to handle the character’s jumping input:
csharp
if (Input.GetButtonDown("Jump") && isGrounded)
{
rb.AddForce(new Vector3(0f, jumpForce, 0f), ForceMode2D.Impulse); // add a force to the character’s rigidbody component in the upward direction and trigger the "Jump" animation
anim.SetTrigger("Jump"); // trigger the "Jump" animation
isGrounded false; // set isGrounded
to false so that the character can no longer jump after landing
}
Adding Animations
Now that our controller is working, we can add some animations to make our character look more realistic. First, we need to create two new animations in Unity: “Walk” and “Jump”. We can do this by going to “Window” in the menu bar, then selecting “Animation” and choosing “Create Animation Clip”.
Once we’ve created our animations, we can drag them into our character controller script and set them as public variables:
csharp
[SerializeField] Animator WalkAnim; // reference to the "Walk" animation clip
[SerializeField] Animator JumpAnim; // reference to the "Jump" animation clip
Next, we need to create some trigger animations for our jumping and walking inputs:
csharp
void FixedUpdate()
{
float moveX Input.GetAxis("Horizontal") moveSpeed; // how fast the character moves
float moveY Input.GetAxis("Vertical") moveSpeed; // how fast the character moves
Vector3 targetVelocity new Vector3(moveX, rb.velocity.y, moveY); // calculate the target velocity for the character’s rigidbody component and set it accordingly
rb.velocity targetVelocity; // set the character’s velocity to the target velocity
if (!isGrounded) // if the character is not on the ground
{
anim.SetBool("IsJumping", false); // stop the "Jump" animation and start the "Walk" animation
WalkAnim.Play(); // trigger the "Walk" animation
}
else
{
if (Input.GetButtonDown("Jump") && isGrounded)
{
rb.AddForce(new Vector3(0f, jumpForce, 0f), ForceMode2D.Impulse); // add a force to the character’s rigidbody component in the upward direction and trigger the "Jump" animation
anim.SetTrigger("Jump"); // trigger the "Jump" animation
isGrounded false; // set isGrounded
to false so that the character can no longer jump after landing
}
else
{
anim.SetBool("IsJumping", true); // stop the "Walk" animation and start the "Jump" animation
JumpAnim.Play(); // trigger the "Jump" animation
}
}
}
We also need to add some code to stop the walking animation when the player lands:
csharp
void Update()
{
if (Input.GetButtonDown("Jump") && isGrounded)
{
rb.AddForce(new Vector3(0f, jumpForce, 0f), ForceMode2D.Impulse); // add a force to the character’s rigidbody component in the upward direction and trigger the "Jump" animation
anim.SetTrigger("Jump"); // trigger the "Jump" animation
isGrounded false; // set isGrounded
to false so that the character can no longer jump after landing
}
else if (!isGrounded) // if the character is not on the ground
{
anim.SetBool("IsJumping", false); // stop the "Jump" animation and start the "Walk" animation
WalkAnim.Play(); // trigger the "Walk" animation
}
else
{
anim.SetBool("IsJumping", true); // stop the "Walk" animation and start the "Jump" animation
JumpAnim.Play(); // trigger the "Jump" animation
}
}
Conclusion
In this tutorial, we’ve learned how to create a simple 2D character controller that can move forward and backward, jump, and perform walking and jumping animations. We’ve also covered how to use Unity’s built-in physics and animation systems to create realistic movement and animation behaviors.