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.
Today’s Objective: Create the most important part of my 2D player controller, the collision detection using Raycasts.
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.
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.
Variables first. These define the body size, raycast length, and where to store the result.
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:
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.
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:
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!