Home Tower Defender - Part 1
Post
Cancel

Tower Defender - Part 1

Enemy movement via NavMesh

The purpose of the blog is to document my journey in building a simple Tower Defense game. In this first part I show how I made the enemy object move towards to the target using Navigation AI (NavMesh).

The following Unity packages will be covered:

Required Packages

The following packages need to be installed from the Unity Registry.

  • NavMesh
  • ProBuilder

Game Platform and NavMesh

Using ProBuilder I created a cube, scaled it down and used it as a platform. Then I added some custom shapes as obstacles for the enemy. For the enemy object I used a simple capsule and for the target a sphere.

Level Overview

Creating a NavMesh

In order to apply AI Navigation needed for the enemy object to find the way to the target, I selected the platform and added the NavMeshSurface component.

NavMesh Surface

Creating an Agent

The capsule is used as enemy and for it to know its way around the NavMesh I added a Nav Mesh Agent to it.

NavMeshAgent

Explain logic to move the enemy and destroy it once the Target is reached

With the NavMeshSurface and NavMeshAgent applied, the next step is to create a C# script and add it to the enemy (capsule).

Above the Start method:

  • UnityEngine.AI has been added to the script since it is needed for the Navigation System
  • Created private variables for the enemy, target, lastPosition and DistanceThreshold to use later in the code.

The Start method:

  • Assign the target variable to the target GameObject (Sphere) and check if the GameObject is available.
  • Assign the NavMeshAgent Component to the enemy(capsule).
  • Tell the enemy object where it needs to go (target position)
  • Assign the enemy position to the lastPosition variable. It will be used later in the FaceDirection method.

The Update method:

  • Calling the two custom methods I created. DestroyOnTarget and FaceDirection.

Custom function - DestroyOnTarget:

  • The purpose of this method is to destroy the enemy GameObject once it reaches the target.
  • The code checks the distance between the enemy and the target. If the enemy is closer then 0.3 units (Threshold), the condition becomes true and the enemy GameObject will be destroyed.

Custom function - FaceDirection:

  • Assign a new Vector3 variable Direction and assign it the current position of the enemy object.
  • The if condition checks if the enemy is moving and if so, it will rotate (Z Axis is the front) the enemy to look in the direction of the movement.

The complete C# code for the enemy movement script

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
using UnityEngine;
using UnityEngine.AI;

public class EnemyMovement : MonoBehaviour
{
private NavMeshAgent agent;
private GameObject target;
private Vector3 lastPosition;
[SerializeField] private float ThresholdDistance = 0.3f;

    void Start()
    {
        target = GameObject.Find("target");
        if (target == null)
        {
            Debug.LogError("Could not find the 'target' object.");
            return;
        }

        agent = GetComponent<NavMeshAgent>();
        agent.destination = target.transform.position;
        lastPosition = transform.position;
    }

    void Update()
    {
        if (agent.velocity.magnitude > 0)
        {
            FaceDirection();
        }
        DestroyOnTarget();
    }

    void DestroyOnTarget()
    {
        if (agent.remainingDistance <= ThresholdDistance)
        {
            Destroy(gameObject);
        }
    }

    void FaceDirection()
    {
        Vector3 direction = transform.position - lastPosition;

        if (direction.magnitude > 0.01f)
        {
            transform.LookAt(transform.position + direction);
            lastPosition = transform.position;
        }
    }
}

Game preview

First Run

This post is licensed under CC BY 4.0 by the author.