Fortress Defense

My WWII-themed tower defense game features all pixel art created by me, capturing the gritty atmosphere of the era. Developed over seven weeks, it features an upgrade system, enemy waves and an unit grid placement.

My Code

Enemy Spawning System

This feature spawns enemies with a delay between each spawn, randomizing their types and spawn locations within each wave.

Enemy Spawning Code


      private IEnumerator SpawnEnemiesWithDelay()
      {
          for (int i = 0; i < currentWave.NumberToSpawn; i++)
          {
              int enemyIndex = Random.Range(0, currentWave.EnemiesInWave.Length);
              int spawnPointIndex = Random.Range(0, spawnpoints.Length);
      
              Instantiate(currentWave.EnemiesInWave[enemyIndex], spawnpoints[spawnPointIndex].position, spawnpoints[spawnPointIndex].rotation);
      
              enemiesSpawned++;
      
              if (enemiesSpawned < currentWave.NumberToSpawn)
              {
                  yield return new WaitForSeconds(currentWave.TimeBtwnSpawn);
              }
              if (enemiesSpawned == currentWave.NumberToSpawn)
              {
                  incrPossible = true;
              }
          }
      }
          

This code spawns enemies in waves. For each enemy, a random type and spawn point are chosen, and after a delay, the next enemy is spawned. When all enemies for the current wave have been spawned, the system flags that it's ready to move on to the next wave.

Building Placement and Collision Detection

This feature handles building placement in a grid-based system, checks if the position is buildable, and detects potential collisions with existing objects.

Check Buildable Area Code


      public bool IsPositionBuildable(Vector2 position)
      {
          RaycastHit2D hit = Physics2D.Raycast(position, Vector2.zero, Mathf.Infinity, buildableArea);
      
          if (hit.collider != null)
          {
              return true; // Position is within the buildable area.
          }
      
          Debug.Log("collider hit");
          return false; // Position is outside the buildable area.
      }
          

This function checks if a given position is within a buildable area using a raycast.

Mouse Position and Building Placement Code


      mousePosition = Camera.main.ScreenToWorldPoint(Input.mousePosition); // Get mouse position
      mousePosition.z = 0f;
      
      closestTile = gridTilemap.WorldToCell(mousePosition); // Get closest tile based on mouse position
      Vector3 closesTilePos = gridTilemap.GetCellCenterWorld(closestTile); // Get center of the tile
      
      if (Input.GetMouseButtonDown(0) && building == true)
      {
          Debug.Log("it clicks");
          buildable = GameObject.Find("BuildableArea").GetComponent().IsPositionBuildable(mousePosition);
          bool noCollision = GetComponent().CheckForCollision(closesTilePos);
          Debug.Log(noCollision);
          
          if (buildable && GameManager.selection && noCollision)
          {
              if (GameManager.manPwr - GameManager.selectedUnit.GetComponent().price < 0)
              {
                  Debug.Log("Not enough resources");
                  building = false;
                  return;
              }
              else
              {
                  GameManager.manPwr -= GameManager.selectedUnit.GetComponent().price;
                  Instantiate(GameManager.selectedUnit, new Vector3(closesTilePos.x, closesTilePos.y, -1), Quaternion.identity);
                  building = false;
              }
          }
      }
      else if (Input.GetMouseButtonDown(0) && removing == true)
      {
          Collider2D[] collisions = Physics2D.OverlapBoxAll(new Vector3(closesTilePos.x, closesTilePos.y, -1), new Vector2(1,1), 0);
          if (collisions.Length > 0)
          {
              foreach (Collider2D collider in collisions)
              {
                  Destroy(collider.gameObject);
              }
              return;
          }
          return;
      }
          

This code tracks the mouse position for building placement, ensuring it is buildable and collision-free before placement. It also supports removing objects with a mouse click.

Collision Check Code


      public bool CheckForCollision(Vector2 position)
      {
          colliderSize = GameManager.selectedUnit.GetComponent().size; // Get the size of the current unit's collider
          Collider2D[] colliders = Physics2D.OverlapBoxAll(position, colliderSize, 0, collisionLayer);
      
          if(colliders.Length > 0)
          {
              foreach (Collider2D collider in colliders)
              {
                  Debug.Log("Collision detected with: " + collider.gameObject.name);
                  // Handle the collision here.
              }
              return false;
          }
          return true;
      }
          

This function checks for collisions using an OverlapBox and logs any detected collisions, returning `true` if no collision is found.

Finding the Nearest Enemy

This feature locates the closest enemy to the player, tracking the nearest target in real-time for targeting purposes.

Find Closest Enemy Code


      void FindClosestEnemy()
      {
          enemies = GameObject.FindGameObjectsWithTag("Enemy");
          float shortestDistance = Mathf.Infinity;
          Transform nearestEnemy = null;
      
          foreach (GameObject enemy in enemies)
          {
              float distanceToEnemy = Vector2.Distance(transform.position, enemy.transform.position);
              if (distanceToEnemy < shortestDistance)
              {
                  shortestDistance = distanceToEnemy;
                  nearestEnemy = enemy.transform;
              }
          }
      
          targetEnemy = nearestEnemy;
      }
          

This code searches for all active enemies by tag, calculating the distance between the player and each enemy. The closest enemy is then stored as the current target for further interaction.

Suggested Projects

Vertical Slice

A group school project to remake a proffesional game

C# Icon Visual Studio Icon Unity Icon Blender Icon
Project Image

Brawler

A simple stage fighter game. This was my first game made in Unity, and first experience with C#

C# Icon Visual Studio Icon Unity Icon
Project Image