
Units
In this game, there are two types of units: Player Controlled and AI-controlled. The player has multiple units in his squad. A circle is below the unit that the player has currently selected. Enemy units are colored red while player units are colored white. All of the units can execute different actions ranging from moving to different styles of fighting.
The unit selection works with a ray trace from the mouse cursor to the world and detects if a unit is hit. If the unit is not valid due to different reasons; such as it is dead, or an enemy, the ray trace will return false, and therefore the unit will not be selected.
Grid System
Since the grid is the core of this project my goal was it to make it as perfect as possible. The grid is set up in a dynamic way. This makes it possible to easily adjust the size of it or to call important functions. The grid converts the world space into its own grid space with two grid positions Grid.X and Grid.Y. All of the unit actions are based on the grid, rather than a unit moving to the world position X: 0, Y: 0, Z:0 the unit is instead moving to grid position X:0, Z0. This allows for easy calculations when adding new mechanics into the game.
For the grid positions, I could have used Unity's build in Vector2 but I decided not to do that the main reason being that Unity's Vector2 is based on X and Y and I have to work in X and Z dimensions since Unity's world space Y dimension is the up vector. This would have led to weird calculations and not clean code.


Camera Controls
The player is able to freely control the camera. He can move it, rotate it, and zoom in and out. For this project, I decided to use Unity's Cinemachine to create the camera. There are special effects for certain actions such as an action camera that automatically zooms in on combat actions and screenshake which triggers on damage event.
Unit Actions
The Unit Action System is a dynamic system that I implemented to easily add more mechanics to the game. Every unit has a variety of actions at their disposal. Actions can be easily added and removed from units without creating errors. This allows units to have different sets of actions available. When adding or removing an action to a player unit the User Interface for the player is automatically updating and showing only the available actions. This system was created in a way in which player units and AI units can share the same actions. This has the advantage of creating a new mechanic only once and then being able to use it for both teams. Every taken action consumes an action point. Units have 2 action points per default but it can vary from unit to unit.
Movement Action
The units can only move on the grid. The movement action is using pathfinding in order to find the best way to their destiny. If there is an obstacle in the way of the unit it will automatically walk around it and this will not be an available destination for the unit to move to, the player can't select it. Checking for obstacles happens from the grid. A ray trace is fired of each grid positions center in the upwards direction. If the raytrace hits something the grid position will be assigned a value of invalid. Certain actions need to be requested, if the position is valid in order to be an available action. If a unit needs to walk around an obstacle it will not be able to walk its full range. The unit movement action range is calculated using the path distance rather than the direct distance. This is also visible in the grid visual.

Shoot Action
The unit can shoot an enemy unit in range. This action damages the opposite unit. If a unit drops below zero hitpoints it dies and can no longer be controlled. The grid visuals only show valid targets. For a target to be valid it needs to be in range and valid.

Grenade Action
The unit can throw a grenade on a field with and without a unit on it. The grenade does splash damage to all units in a certain radius. Since the grenade doesn't need a specific target to be thrown at it can also afflict damage to units on the same team.

Sword Action
The unit can slash a sword at an enemy. This action can only be executed if the target is on an adjacent field. However, it also one-hits the targeted unit. When executing this action the character model swaps its equipped weapon from a rife to a sword.

Interact Action
The unit can interact with different objects in the world such as doors or lights. The interact code is based on interfaces which makes it easy to add new interactable objects to the action. For an object to be interactable it just needs to implement the interact interface.


Enemy
The enemy is a prefab variant of the player unit. The core features of being a unit are the same for the enemy. It can use the same actions as the player units and all the features that come with it, such as the pathfinding on the movement. The enemy AI works with different states and it evaluates which state is the best state to defeat the other units. The highest priority of the AI is to kill all of the player units and therefore win, if there is an obstacle in the way of reaching that goal, for instance, the distance is too far or the target is out of sight then the AI will make the right decisions to maneuver around that obstacle. The AI also always targets the lowest health unit in order to guarantee the kill.
Future
I think I was able to create a solid foundation. In the future, I would like to expand this project even more. I would like to add new game modes, multiple floors, more actions, and more enemies to the game. In addition to that I would like to try to create a grid system based on hex grids.