Creating a Character Controller in Unity


Before getting into it, check out the finished product.

The released playable version is here but feel just as free to just check out the video instead.

Intro

Hello! This blog post will describe my day-by-day process of creating a character controller in Unity.

This is not the first character controller I've made in a game engine before. I've made lots! So I will be repeating what I've done before just in different engines and drawing from that experience.

This is also not my first time using Unity, but it is my first time making a character controller that I can recall.

To remove any confusion, what I am calling a "character controller" is just a system of managing player input, character movement, character state, and animations. In other words, all code a game developer writes to manage the movement of the player's character in a finished game, as the player perceives it. This tends to vary greatly from game to game and there is no fixed definition of what it entails. I am not referring to Unity's component named CharacterController, though I will be building with it as a base.

Days 1 & 2 - Reading Documentation

I spent a couple days just reading over the documentation for Unity before even setting up a basic project.

I've learned through my time coding how important it is to be familiar with the concepts & tools available to you before writing any line of code.

Day 3 - Basic Movement

This is the first day I spent actually creating stuff in Unity. At the end of this day I have set up a basic character controller using Unity's CharacterController component, including:

  • User input (both mouse/keyboard & controller) and translating that to basic character movement (moving left/right, forward/backward relative to the camera)
  • Jumping, short jumping, and gravity
  • Rudimentary camera controls
  • Resetting the character position if it falls off the map to make testing easier
Going forward my focus will need to be modeling & animating a simple character model (and learning how to import and work with that in Unity) as well as implementing proper state management for the various character states. Once I have that in place, I'll end up offloading much of the current code to those states. I'd also like to add additional functionality to the camera, mainly the ability to zoom in/out as well as collide with the level geometry rather than phase through it. These are things I've done in other engines and just need to learn the Unity way of doing it.

Day 4 - Camera Controls & Coyote Time

Today I added additional functionality to the camera including:

  • Ability to zoom in/out in a variety of ways. Mouse scroll wheel, I/O/+/- keys on the keyboard, and the right thumbstick press on gamepad to cycle through 1/4th increments of the max camera zoom distance
  • Collision with geometry by using a sphere cast
  • Smoothing when zooming out to make camera popping from occlusion less noticeable
  • Pressing Esc now toggles mouse lock

And some tweaks to character movement, including:

  • Implemented coyote time. Coyote time is a term for allowing the player's jump input to still work for a brief moment after leaving the ground and is a common way to make game controls feel better and more forgiving.
At this point, moving around both the character and camera feels great and I feel ready to start adding the character model, but I really need to implement proper state management for the various character states before adding anything else or the code is going to get messy quickly.

Day 5 - Character State Management

The approach for managing character state I'm going with is a fairly straight forward method. Each character state is its own class which overrides methods from a base character state class. These methods are:

  • StartState
  • StopState
  • UpdateState
  • FixedUpdateState

At any time a state may call a method in my main character controller to transition to another state, such as when landing from a jump.

There can only be one currently active state. By making sure there can only be one currently active state, this greatly reduces code complexity and makes implementing character behavior intuitive and straight forward.

From experience having multiple states/character flags which control character behavior active at any given time adds unnecessary runaway complexity without any real benefit. You can still share functionality between states (e.g. by calling shared methods or inheriting from another state.) This just ensures you can easily tell exactly what state the character is in and what the code is doing at any given time.
I choose to make my own versions of update and fixed update methods rather than using the built-in ones provided by Unity's MonoBehavior for the simple reason of being able to choose exactly when they're called by my character controller.

Day 6 - Modeling & Animating a Character


I modeled a character in Blender, intentionally keeping things simple. I want to have a character and animations but I'm not trying to make a finished game asset for any game in particular. That said, I quite like this guy.

I set up his skeleton & weight painting next, and then finally animations. For the animations, I've created one for each of my current character states.

Next up is figuring out how to handle character animations in Unity.

Day 7 - Adding the Character Model

I added the character model I created, set up the animations, and made it rotate towards the direction of movement. It was slightly more complicated than that, but that's the short version.

I've completed my goal now of creating a character controller in Unity. But since I've come this far, I have a couple extra ideas to spice it up.

As an aside, I really like how I can forgo all the state machine stuff in Unity's animation system and just call a method to directly go to any state at any time, from any other state. My code is the only authority of state I'll ever need.

Bonus - Diving and Ledge Detection

I could keep going forever. I love thinking of new ways to expand on character movement. But this was never meant to be that kind of long-term project so I'm cutting it short here before I get carried away.

Obligatory Godot is better anyway comment

If you've made it this far and are interested in looking at the code or the Unity project, you can access them here. Please do not use the character model for any commercial and/or publicly released projects. Replace it ASAP if you plan to build something with this project as a base. Thank you!

Files

Windows 64-bit (Portable) 34 MB
3 days ago

Get Character Controller in Unity

Leave a comment

Log in with itch.io to leave a comment.