Improvements

If I were to improve my game, the first area is to improve the aesthetics of the game. Currently, all of the different types of drone all have the same model which makes it hard to find which type is which. Also the sprites could be improved by increasing the detail of them, which will make the game nicer to look at. The UI could also be improved for similar reasons.

The AI of the drones could be vastly improved. One area that needs to be implemented is a form of path finding. This is because currently, the drones aren’t aware of obstacles so will often bump into walls and each other. Only after bumping into the wall will it turn away from it.

There is also a large bug that should be fixed where if a drone is destroyed that a commando drone is targeting, it will not move before targetting the next drone. This means that the commando drone, in this situation can have global range.

I could also make the game more interactive by adding in levels to complete with a scoring system based on what drones are used and what drones were killed.

Adding Randomness

To make the game more replayable, I have added random values to two elements of the game – the damage that the shots do and the accuracy of the shots. The accuracy is also a form of artificial stupidity to make the game more realistic and less frustrating for the user. To make these variables random, I used the method Random.range(low, high).

For the accuracy, I changed the value of the z component of the rotation of the spawn point. This was done by getting a random value between the initial spawn rotation plus/minus a set amount. Before adding this value to the bullet, a check needs to be done to see if the random value is above 360 or below 0, otherwise it will not work properly when it is converted to a quaternion.

The damage is much simpler to add random values to. After instantiating, a random value is created between a low and high point of damage. Then the SendMessage function is used to pass this value through to the instance of the bullet.

 

The code snippet below shows how a random angle is created for each bullet.

Vector3 angles = shotSpawn.rotation.eulerAngles;
 
float zMax, zMin;
zMin = angles.z - 10f;
zMax = angles.z + 10f;
 
if(zMin < 0)
{
    zMin = zMin + 360;
}
if(zMax > 360)
{
    zMax = zMax - 360;
}
angles.z = Random.Range(zMin, zMax);
 
Quaternion bulletRotation = Quaternion.Euler(angles);

 

More Types of Drone

The next stage of development of my game was to add more types of drone. The first was a sniper type drone which shoots high damage, long-range shots but is slow to reload and does not have much health. I have also designed the drone to run away from attacking drones.

Skirmish Drone

To get the drone to flee from enemy drones that are attacking, I have added another GameObject as a child to the skirmish drone so I can add another circle collider to it (you can’t add multiple colliders to the same object). I have then created a script so that when an enemy enters the radius of the circle collider, it triggers a response to flee in the movement script.

CircleCollider

Circle Collider Radius

After the enemy has exited the radius and the drone has fled from him, the drone can then stop to shoot the enemy. The drone will target this enemy as it is the most threatening.

To flee from the enemy, the flee method calls TurnAway which turns the drone away from the targeted drone (which will be the one targeted by the collider). Below is a code snippet of the TurnAway method which turns the drone away from the target based on the speed of the drone.

private void TurnAway(GameObject newTarget)
{
    Vector3 targetDirection = newTarget.transform.position - transform.position;
    float step = speed * Time.deltaTime * 10;
    float angle = Mathf.Atan2(targetDirection.y, targetDirection.x) * -Mathf.Rad2Deg;
    Quaternion q = Quaternion.AngleAxis(angle, Vector3.forward);
    transform.rotation = Quaternion.Slerp(transform.rotation, q, step);
}

For attacking, a very similar method is used, but reversed so the drone faces towards the target.

 

Commando Drone

Another type of drone that I have come up with is the commando drone which is another ranged drone, but the opposite of the skirmisher as it has a high rate of fire, but low range and low damage. I have used similar principles of the previous drones where the drone has a child that holds a trigger collider, but this one is for working out the range of the drone. When an enemy drone enters the collider, the drone stops and attacks that drone, and if it leaves, it chases.

 

To shoot, I have a public variable called fire rate which can be modified from Unity. This determines the speed at which the drone shoots. The following is used to see if the drone can shoot and calculates when it should shoot next.

if (Time.time > nextFire)
        {
            nextFire = Time.time + fireRate;
            ...

Both the commando drone and the skirmish drone shoot the same bullet. This bullet has its own script that destroys itself when it collides with anything so the game area isn’t cluttered with old bullets. The script also holds methods to set the damage of that bullet, so when the bullet is instantiated in the skirmish/commando script, the damage can be set. This allows the different drones to have different damages. When the bullet hits a drone, the bullet calls the health component of the drone to take whatever damage it is set to.

OpenAI Five

I am going to diverge from talking about my project and talk about a very interesting advancement that has been taking place over the last couple of years with the OpenAI Five which is a team of five AI bots that have been competing verses human players at the game DOTA 2.

Last year (2017), the AI was developed to only play the simpler 1 v 1 game mode, where the AI excelled and beat many professional players at the biggest tournament of the year. However, after some time, the human players started winning since the AI was predictable in what it would do next.

This year (2018), the AI has been trained to play as a team which means that each neural network has to work together without explicit communication between the networks. It was taught how to play by playing approximately 180 years worth of games every day, and learning from mistakes that it makes to improve future iterations of the neural network. The team of AI bots started strong, beating amateur and semi-pro players, but failed to win against the professional teams. This was still considered a success though as the AI can now evolve and be trained to learn from the mistakes in the games.

This OpenAI project is far beyond the complexity that I need for this project, but is very interesting how far you can go in the field of AI within games.

 

Moving the Drones

The next step that I took was to make the drone move. This was only a very simple script that spawned the drone in and set it moving in whatever direction that it was spawned in at. Making the drone move forward was done with the following line of code:

GetComponent().velocity = transform.right * speed;

The first part of the line gets the velocity of the object which has to be done by calling the RigidBody component of the object which was assigned to it in the Unity window. Transform.right sets the object moving by 1 unit, so multiplying it by the public variable speed allows the object’s speed to be tuned from within Unity and even at runtime.

I originally put this in the Start() function so the drone would be given a set velocity, but after some testing with collisions with other drones, I found that it lost all velocity. I then tried putting it in Update(), but this was called too often, which made the drones hit and bounce off each other many times per second. In the end, I used a function called InvokeRepeating, which calls the method in the parameter a specified amount of times per second. This works quite well, as the drones can now bounce off each other before attacking each other again.

Making the drones move in different directions was much more of a challenge, because they had to face something, which meant a way to target enemy drones. At first, I implemented a primative targeting method where the closest drone is targeted, but I had trouble when the target died, it threw a null exception error since the object had been destroyed. To counter-act this, I created a targeting class, improved the logic of my method and called this class every time the targeted object == null.

Here is some pseudo-code of my targetting algorithm:

  • Get array of all of the enemy drones
  • Set the minimum distance to infinity
  • for each object in array
    • Calculate difference between the current drone and the drone in array
    • Set it as target if it is less than the minimum distance
  • Return target

 

Starting the Game

Initially, to start off the game, I made a simple drone model so that I have got something to program. I started off in Microsoft Paint, because of its simplicity and the fact that I already have it installed. I quickly found that it wasn’t detailed enough for my needs as there was no method of making the background transparent. Below is my first attempt in MS Paint. Also notice I messed up the size of the shape, so the top and left side of the circle are cut off.

drone
Version 1 Drone

After finding this problem, I decided to use Paint.net as it is much easier to remove the background and do other, more advanced tasks. After getting acquainted with the software, I created this:

 

drone_v2
Version 2 Drone

This is a much better improvement to the first version, and is a much cleaner image.

The reason for the turret, is mainly to show what direction the drone is moving in when in the game view.

This drone sprite is the minimum of what I need for the project, but enough to get me started coding.

 

Tutorials

So the first tutorial I used was a 20 minute Pong replica tutorial that was posted on YouTube as linked here. I completed this quite quickly, but found that the tutorial was not in-depth enough, and trying to add onto this game with scoring and an AI opponent, I found that I still did not have the knowledge to complete this, so I went and found another tutorial.

I decided to use one of the tutorials that were linked on the Unity launcher because they looked more detailed. The tutorial I chose was the 2D Space Shooter. I chose this one specifically, initially because it was the only top down 2D one in the beginner category, however, even though it was labeled as 2D, it still used Unity 3D, just in a 2D perspective. After completing the tutorial I have the following comments:

  • It was very slow – I had to increase the speed up to 1/4 more than normal and skip some extremely obvious parts, although this is better than the other way I guess
  • It was quite outdated – some of the syntax is completely incorrect and I had to research workarounds

Despite the drawbacks, this tutorial gave me the knowledge and the confidence for me to complete my game.

Learning Unity

Over the past couple of weeks, I have been learning how to use the game engine Unity. First of all, I have gone through the built-in basic tutorials on the Unity software. The purpose of this basic tutorial is to learn the UI, where the buttons are and what they do. I have also started looking at YouTube tutorials on how to use the program. I will do one more tutorial project before I will start on my main project, just to make sure that I am fully comfortable on using Unity. I will try to find one that is in a similar style (2D top-down) to my idea of a drone-like battle simulator so then I can see how it is done and get some inspiration when I am doing it on my own.

Starting the Project

To start the project, I have been looking at different project examples that other people have made in both Unity and NetLogo to decide which one to choose for my own project. I feel like Unity is the better choice since it has more resources to freely use and it is developed primarily for games rather than NetLogo which is more targeted for modelling. My first idea for the game is to create a battle simulation game similar to Totally Accurate Battle Simulator or the battles in the Total War franchise, but more basic and from a top down perspective (and maybe with drones rather than troops). I think that to make it more of a game rather than a simulation, the user should have a set amount of money and choose which type and how many drones to attack an enemy. There also could be different levels of increasing difficulty where the enemy gets stronger or the user has less money or there could be unique obstacles to create variety.