Creating An Advanced 2D Player Controller Without Any Unity Components! (Part 2)

In this post, I am creating the raycast-based collision detection for my 2D player controller.

Raycast collision detection

Today’s Objective: Create the most important part of my 2D player controller, the collision detection using Raycasts.

The Design:

The “Body”:

Because this controller aims to not use other Unity components, I will use a series of Raycasts to detect collisions around the “body”. The “body” of the character is actually a 3D rectangle around the center point, known in Unity as a Bounds variable.

This Bounds “body” has no connection what-so-ever with the rest of the GameObject/character form, so be sure to set it to an appropriate size for your character.

The Raycasts:

I’ve decided that the setup for the raycasts will be as follows:

  • 4 “Main” raycasts will be the primary detection in each of the up/down/left/right directions.
  • 8 “Secondary” raycasts will be secondary collision detections for more detailed information. E.g. Is the character at the edge of a cliff, is there a waist-height step in front of them, etc.
Raycast diagram

The Code:

Variables first. These define the body size, raycast length, and where to store the result.

Specify body size, correction style, Ray length, relative positions, and result storage.
Create Rays as Properties, since their origin points change whenever the player moves.

Now, so we have an idea of how things are looking so far, I will create the Gizmos now:

Still within the DrawGizmos method, here comes the code to display the Rays I created:

What we’ve now created:

The rays go from the center so that they can detect when the body is inside something it shouldn’t be.

Now to create the method that actually checks for collisions:

The script now knows when it is colliding, where, and with what, but that still doesn’t stop it from passing through anything. I need to create the method which will correct the object’s position, based on the detected collisions.

My current method is just over 100 lines with a lot of duplicated code which I am still trying to minimize, so I will only show a smaller section. From this, you should easily be able to duplicate it for the rest of the rays as needed.

For each of the directions, the code is set up to prioritize Rays in a certain order:
— Main Rays before Secondary Rays.
— Down before Up, Left before Right.
This prioritization avoids the errors that could come from e.g. Somehow being stuck between two objects on left and right which are too close, trying to correct position for both directions simultaneously, leading to an unstable object position.

The starting setup code in the collision correction method.
The collision correction code for the DOWN direction

Finally, add both methods into the Update method so that they are called when in Play Mode:

For anyone still confused as to what the corrections are doing, here’s a diagram:

The red/white squares are its actual current position. The capsule is only there because this is Edit Mode and I am forcing it. It’s a visual glitch.

It still has issues when it is pulled/pushed too far into an object, however that should only be possible in Edit Mode since I am forcing it. During runtime, it will keep correcting itself to basically never get that far in.

Hopefully that all made sense to you. :)

In tomorrow and the following day’s posts, I will be adding more features to this controller for the gameplay side of things.

Thanks for reading!

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Vincent Taylor

Vincent Taylor

Unity game developer / C# Programmer / Gamer. Australian (Tasmanian) indie games developer for 10+ years. Currently looking for games industry employment.