---
description: >-
  In this section, we took the time to add enemies to our level with AI behavior
  for patrolling and chasing the player.
---

# Section 5: Adding Enemies

## Section Intro - Adding Enemies

There are no notes for this lecture.

## Designing an Enemy

In this lecture, we took the time to prepare an enemy scene with animations. There are no notes for this lecture.

## Refactoring the State Machine

In this lecture, we refactored the state machine by taking advantage of inheritance. Now that we're introducing a second character, we want to be able to reuse code. For this reason, we refactored the states and character classes by creating a generic class, which holds code that will be used by multiple classes. Here's the hierarchy of classes.

* Character
  * Player
  * Enemy
* CharacterState
  * PlayerState
    * PlayerIdleState
    * PlayerMoveState
    * PlayerDashState
  * EnemyState
    * EnemyIdleState

## Drawing Patrol Paths

In this lecture, we learned how to use the **Path3D** node to draw paths. There are no notes for this lecture.

### Resources

* Path3D - [https://docs.godotengine.org/en/4.2/classes/class\_path3d.html](https://docs.godotengine.org/en/4.2/classes/class_path3d.html)

## Creating the Enemy Return State

In this lecture, we worked on the enemy return state. First, we grabbed a reference to the node that stores the path.

```csharp
[Export] public Path3D PathNode { get; private set; }
```

Next, we were able to grab the path from the `Path3D` class with the `Curve` property, which is a resource containing the path data. On this property, we accessed a specific point on our path with the `GetPointPosition` method.&#x20;

```csharp
Vector3 localPos = characterNode.PathNode.Curve.GetPointPosition(0);
Vector3 globalPos = characterNode.PathNode.GlobalPosition;
destination = localPos + globalPos;
```

Points on a path are stored in an array. This method returns a specific point's position, which we can specify by passing in an index. After grabbing this position, we added it to the global position of the `PathNode` because the `GetPointPosition` method only returns a local position. If we ever want a global position from a local position, we must add the local position with the parent's global position. After grabbing this information, we set the `destination` variable to the result.

All nodes have the `GlobalPosition` property, which is inherited by the `Node3D` type.&#x20;

## Moving the Enemy

In this lecture, we learned how to calculate the destination for an enemy. First, we learned about the `GlobalPosition` property, which is available on all `Node3D` types. This property always stores the global position of the node in our world.&#x20;

Afterward, we used a method called `DirectionTo`, which is available on `Vector3` types. This method calculates a property direction between the current position of an object and another position. It accepts a `Vector3` value as an argument like so:

```csharp
characterNode.GlobalPosition
    .DirectionTo(destination);
```

During this process, we had to detect that the enemy reached their destination. However, this process won't go smoothly if the current position of a node and destination aren't exact. That can be hard to check if you have physics enabled, as some areas may be completely unreachable. For this reason, we're going to use Godot's navigation system in the following lecture.

## Baking a Navigation Mesh

In this lecture, we learned how to bake a navigation mesh, which is data that tells our game what areas are walkable. While optional, it's recommended to bake a navigation mesh, as generating a mesh can be an expensive task. Baking is the process of storing the results of a complex task before the game has been built.&#x20;

A navigation mesh can be generated with the `NavigationRegion3D` node. This node stores a resource with the navigation mesh and can even help you generate the mesh. As long as you add the obstacles and environments as a child to this node, you should be good to go when generating the mesh.

## Navigation Agents

In this lecture, we updated our enemies to be navigation agents. Godot has a script called the navigation server that is responsible for keeping track of the navigation area, obstacles, and agents. Agents are the movable characters in our game that can use the navigation mesh. Before an agent should move, it should check with the navigation server if it can do so.

We can communicate with the navigation server with the `NavigationAgent3D` node. By adding this node, we'll be able to use its methods.&#x20;

Firstly, we notified the navigation server of a new location by updating the `TargetPosition` property.

```csharp
characterNode.AgentNode.TargetPosition = destination;
```

Next, we used the `IsNavigationFinished` method to detect if the agent reached their destination.

```csharp
if (characterNode.AgentNode.IsNavigationFinished())
{
    // Some code...
}
```

Unlike before, the agent doesn't need to arrive at their destination exactly. If they get close enough, Godot will let you know that an agent has arrived at their destination.

> It's important that you set the destination on the frame before calling the `IsNavigationFinished` method. Otherwise, Godot might complain that a target position hasn't been set.

## Enemy Patrol State

In this lecture, we created the enemy patrol state. There are no notes for this lecture.

## Patrolling the Path

In this lecture, we got the enemy walking from point to point on the path. Firstly, we waited for the enemy to reach a point by subscribing to the `NavigationFinished` signal. This signal gets emitted when an agent reaches their target position.

```csharp
characterNode.AgentNode.NavigationFinished += HandleNavigationFinished;
```

Afterward, we learned about the `Mathf.Wrap` method to make sure that the next point in the path exists. This method will make sure that a value stays within a range. If a value extends beyond the range, the value gets wrapped around.&#x20;

```csharp
pointIndex = Mathf.Wrap(
    pointIndex + 1, 0, characterNode.PathNode.Curve.PointCount
);
```

There are three arguments, which is the value to check, the minimum threshold and maximum threshold. For the maximum threshold, we can grab the number of points in a path via the `PointCount` property on the `Curve` property.

While moving the enemy, it's important to call the `GetNextPathPosition` method so that the navigation server is informed that the agent is moving.

### Resources

* NavigationAgent3D - [https://docs.godotengine.org/en/stable/classes/class\_navigationagent3d.html](https://docs.godotengine.org/en/stable/classes/class_navigationagent3d.html)

## Pausing on Patrols

In this lecture, we set up a timer to force an enemy to pause when they arrive at a destination before moving on to the next one. We used the `Timer` node to accomplish this task. To make the game more random, we configured the `WaitTime` property each time to a random time with the `RandomNumberGenerator` class.&#x20;

```csharp
RandomNumberGenerator rng = new();
idleTimerNode.WaitTime = rng.RandfRange(0, maxIdleTime);
```

We must create a new instance of this class to use it. Once we do so, we can call the `RandfRange` method to generate a random float value. This method accepts a minimum and maximum range. The value returned by this method is assigned to the `WaitTime` property on the `Timer` node.

To check the timer stops before moving to a new destination, we're checking the `IsStopped` method, which will tell us if a timer has stopped running.&#x20;

### Resources

* Godot Documentation - [https://docs.godotengine.org](https://docs.godotengine.org)

## Exiting States

In this lecture, we took the time to set up exit states in our state machine. In some of our states, we're subscribing to signals. However, we should unsubscribe from these signals to prevent our state from remaining active. To do so, we had to set up an exit state. The setup is similar to the enter state.

To unsubscribe from a state, we would use the `-=` operator instead of the `+=` operator. Here's an example of us unsubscribing from the `NavigationFinished` signal.

```csharp
characterNode.AgentNode.NavigationFinished -= HandleNavigationFinished;
```

## Detecting the Player

In this lecture, we added a `Area3D` node to the enemy to help us detect bodies. This node is designed for detecting nodes with physics on them, such as the player using the `CharacterBody3D` node. On this node, we can listen for when a body is detected with the `Bodyentered` signal.

```csharp
characterNode.ChaseAreaNode.BodyEntered += HandleChaseAreaBodyEntered;
```

One lesson we learned during this process was how to register methods for signals with parameters properly. If a signal has a parameter, our method must include that parameter. Otherwise, it'll be rejected by C#. In the case of the `BodyEntered` signal, our method must have a parameter called `Node3D` like so:

```csharp
protected void HandleChaseAreaBodyEntered(Node3D body)
{
    
}
```

### Resources

* Area3D - [https://docs.godotengine.org/en/stable/classes/class\_area3d.html](https://docs.godotengine.org/en/stable/classes/class_area3d.html)

## Chasing the Player

In this lecture, we learned how to chase the player after being detected by the area node. First, we had to grab the player by using the `GetOverlappingBodies` method. This method returns all bodies that have been detected by an `Area3D` node.

```csharp
target = characterNode.ChaseAreaNode
    .GetOverlappingBodies()
    .First() as CharacterBody3D;
```

In addition, we called the `First()` method to grab the first result. Since the `GetOverlappingBodies` method returns an array and we're only interested in the player, we used this method to grab the first result. However, we have to cast the type into `CharacterBody3D` since the return type is a `Node3D`.&#x20;

In addition, we must include the `System.Linq` namespace since this method is not available unless we add this namespace.

```csharp
using System.Linq;
```

Other than that, everything else we did were things we did before.&#x20;

### Resources

* Godot Documentation - [https://docs.godotengine.org/](https://docs.godotengine.org/)

## Attacking the Player

In this lecture, we worked on setting up the attack state. This state only gets transitioned from the chase state. The chase state was also updated to transition to the return state if the player leaves the `Area3D` node for chasing the player. For this logic, we subscribed to the `BodyExited` signal, which gets emitted when a body leaves an area.&#x20;

```csharp
characterNode.ChaseAreaNode.BodyExited += HandleChaseAreaBodyExited;
```
