// Game Programmer
Upcoming Game Studio
Unreal Engine 4
Crash, spin, and jump in a brand new Crash Bandicoot adventure!
This fangame was an opportunity for me to study and replicate many of the mechanics found in the Crash Bandicoot games (Wrath of Cortex specifically). I found it fascinating looking back to try and find out how certain gameplay mechanics were written, and then trying it myself and looking to improve upon their older methods. Personally, I believe every game programmer should spend time researching and implementing the mechanics found in their favorite games. For this project, I was responsible for most of the vehicular mechanisms found in the game.
Click the buttons below to learn more about how I implemented the core features of the Crash Bandicoot fangame!
Among the largest challenges in the project was designing how the rail cart system would work on a track. My objective was to create a designer-friendly tool to create a track, then place a rail cart vehicle that could ride ontop. Below showcases how the rail can twist and bend along the spline naturally. Basically, between every spline point there exists a rail mesh that rolls to meet the start and end spline point. This creates a smooth twist without any breakages:
Next I had to handle how the wooden planks would spawn in equidistant locations along the spline. I had to use a different method from the rails because wooden planks cannot bend (it would look very odd if they did!). Again, my core focus was making this user friendly, so I added in some parameters to control how far the planks were spaced. The code below shows how an instance of a plank is created along the spline at the correct location and rotation:
Now that the track is complete, my next task was the actual cart itself. It simply updates it's position every frame along the distance of the spline track. I had to account for the fact that distances between spline points varied:
Once the player is inside the cart, they have a few options to play with. Primarily, they can tilt the cart left or right. This is accomplished through an interpolation of roll rotation along a left or right axis:
The results from a higher-level look somewhat like this:
Gliders and airplanes sound like frightening concepts to try and program, but there exists a number of easy solutions to this. The one I chose was to significantly reduce the gravitational pull of the plane in order to keep it stable in-air. Second, I added a pulse every frame to propel the plane in a forwards direction. The rotation I applied tilts the plane and, thusly, the plane's forward velocity is tilted as well. This allows the user to fly left or right:
One of the planes in Wrath of Cortex utilized a lock-on missile. I implemented that by using a rectangular volume that sits directly in front of the plane and spans out a few meters in front. Any enemy plans inside that volume are added to the "Targeted Objects" array. The first plane to be added will be targeted:
Once the missile is launched, it needs to locate it's target and then start traveling to it's world location. I used a bit of 3D vector math to figure out the exact vector to move on.
Now that I had movement and firing, AI was my next priority. Below is a basic overview of the state machine I used for AI flight:
Wrath of Cortex's AI planes weren't anything too complicated. They cycle through two states, an wander state and an attack. The wander state ignores the player and focuses on flying around a large volume. This volume keeps it from flying away from the battlefield. The implementation for this is quite simple. I drew a line trace ahead of the plane to detect obstacles. If it does detect one, it will fly upwards to avoid it.
Similarly, the attack state continues flying, but will rotate it's body to align itself with the player. Once it's forward vector is parallel (done by performing a cross product and detecting the result nears 0), it will begin firing missiles.
The atlasphere is a simple object to replicate from the games. It's essentially uses rolling ball physics. I decided to write my own code for this instead of using UE4's template. One snag I did run into was tying Crash's walking animation to the axis of the player's movement input. I was able to solve this by using the axis as input for Crash's movement, but locking his location relative to the atlasphere.
Furthermore, I was responsible for handling the sound of the atlasphere. When the atlasphere's speed reaches a certain threshold, it emits a rolling noise. Likewise, when it hits against something with a certain velocity, a hit sound will emit. I was able to implement both of these conditions below:
Swimming is a modification on Crash's on-foot mechanics. Firstly, Crash's gravitational scale is tuned very low. Second, the rotation of Crash's model had to fit inline with how it was done in the games. In Wrath of Cortex, when crash turns while swimming, he will only lock to three axis: left, right, and facing the camera. The rest of the rotation is interpolated.
While swimming the player can swim faster, which modifies Crash's left/right movement speed. He can also boost, which activates Crash's spin attack. Any suspended crate in the water will be destroyed if it is nearby Crash's spin attack. The contents of that crate will automatically be collected for the player. The implementation for the boost attack can be found below:
The submarine is, in turn, a modification on Crash's swimming. Crash is inside the sub operating the controls, but the underlying mechanics are still the same. I used the same rotational function in both swimming and submarine movement controllers:
In addition to moving about the water, the sub can also release mines or launch a missile. Releasing mines is as simple as spawning a mine object and letting it's gravitational pull do the work. Launching a missile, on the other hand, requires a forward trajectory either left or right. I also added a constraint that forces the player to only fire when their rotation is either completely left or right. They can't, for instance, fire straight at the camera.