As gameplay programmer on Planetary Planter, a 3D exploration and farming game, the movement system was entrusted to me. Since we've been greenlit last semester, and due to massive changes in the game's structure and level design, I decided that the movement system needed a complete rewrite.
I contacted Champlain's current Game Programming mentor for seniors, Max Anderson, for advice on how I should approach implementing this system. What I took away from that meeting is that I had about 25 years of character controller history to catch up on in order to understand how to make a strong character controller for a 3D game.
For my implementation I started with Unity's Character Controller class and added some basic velocity calculations. Pretty soon I was able to move around and jump, but I wanted to add some more variables to allow the movement to feel more unique and allow the player to feel the weight of the character. These include aerial drag, a lower drag value to apply when no input is received on the ground, and different gravity values for when the player is holding jump.
Once the basics started coming together, it was time to work on resolving specific situations, namely handling slopes. Unity's Character Controller has a built in slope limit that works great for going UP slopes, but doesn't do much else, so I had to implement my own solution.
To solve this problem, I decided to create nine raycasts pointing downward, with eight surrounding the player, representing cardinal and diagonal directions, and one in the player's center. The surrounding raycasts are responsible for surveying the ground for any changes in elevation relative to each other. When the difference in elevation from, for example, the front raycast hit point to the back raycast hit point is too great, it starts pushing the player in that direction, causing them to slide downward towards the direction of the slope the player is on.
The center raycast's use is to ensure that the player is actually on uneven ground. This is to prevent scenarios where the player's feet are close to a ledge, causing the difference in elevation to suddenly become massive and trigger a slide. With the center raycast, so long as the hit point is close enough to the player, slides will not trigger. This doubles as implementation for sliding off cliffs when the center of the player is hovering over the cliff.
My future plans for refining this system include a gliding mechanic and more edge case interactions, such as bumping into walls both on the ground and in mid air, and determining how that should effect velocity.
Comments