top of page

Toy Tank Battle Royale

Solo Unreal Engine 5 Project

Project Overview

Toy Tank Battle Royale was a game I developed in 2 days by myself in Unreal Engine 5, using C++ and Unreal Blueprints. Everything aside from the art assets was built from scratch.

My Role: Technical Game Designer, Programmer
Skills: Unreal Engine 5, C++, Unreal Blueprints

Although I developed a variety of mechanics and systems, ranging from health systems, projectiles, and creating a level map, by far the most challenging task was implementing and enemy that reacts and convincingly fights the player in the short amount of time I had. I'll be talking about the code behind the enemies on this page.

Developing Engaging Enemies
The Aiming and Firing Systems

When I started creating enemies for the game, I began with coding the aiming and firing system. 

I handled this through two functions, RotateTurret, and Fire.

Rotate Turret Function

This function tracks the pawns, the in-game 'characters' if you will, and their current rotation. By comparing their current rotation with their target rotation, and then interpolating at a constant rate between the two, this code allows the pawns to rotate at a natural, constant rate. Since this function was going to be used by all enemy types, I included it in the parent class, ABasePawn, so it could be inherited by all of the child classes based on it, such as the Tower enemy class and the Tank enemy classes.


The C++ code for RotateTurret

Fire Function

I then quickly wrote a simple script to handle the firing mechanic. This one works by taking the location and rotation data of the projectile spawn point component that I attached to each enemy, and then spawning a projectile that shoots forward from there.


The simple firing script

Making Improvements to the Firing System

However, there were some issues with this first implementation. The enemies would fire even when it made no sense to do so, such as when there was a wall between them and the player. To prevent such behavior, I coded in a few more functions so the enemies would check some conditions first before firing their cannons.

Checks and Balances

In my iterated code, I added two new functions to help the enemies decide if they should fire or not. First, the InFireRange function checks if the player is within range of the enemy. Then, the CanSeePlayer uses Line Tracing to check if the enemy has a clear shot at the player, before they finally pull the trigger.


New logic that made the enemies a bit smarter

Coding Movement for Enemies

After getting the aiming and firing functions working, I moved on to implementing movement for the enemies. This was much more difficult than I anticipated, with my multiple earlier attempts resulting in a range of results, from enemies running away, or them twitching and jerking their way towards the player in a horror game like fashion. After testing and using debug logs, I noticed that most problems arose from trying to do too much too quickly, resulting in intended interactions between various parts of the code. To try and simplify my code, I broke down the movement logic into simpler steps.

In the end, a simple, 3 step movement process finally got the results I was looking for. 

1. A random location choosing function which finds a point on the map that is between a minimum and maximum distance between the player and the enemy, to ensure the enemy is neither too close nor too far. Then, it applies a slight offset to the location to make the enemy movement less predictable. 


2. A rotation function that ensures the enemy tank has finished properly facing the target location, before it begins moving in step 3.

3. A movement function which orders the tank forward until it reaches the target destination. Once it is confirmed that the enemy successfully arrived, it triggers step 1 again.

A Happy Accident

Funnily enough, my coolest idea came from a bug in one of my earlier movement code prototypes, which resulted in this awesome Teleporter Tank being born!

Exposing Variables for Easy Access

Throughout all of this development process, I made sure to make all of these variables exposed so that if I were to collaborate with other team mates, they could easily access and edit variables such as movement speed, fire rate, etc. right in the editor, without having to dig through the code!

Facilitating Client Communications

Thanks for checking out Toy Tanks!

bottom of page