---
title: "Create dynamic enemies "
content_type: tutorial
url: "https://learn.unity.com/tutorial/create-dynamic-enemies?language=en"
language: en
difficulty: beginner
unity_version:
  - "6.0"
  - "6.3"
supported_unity_versions:
  - name: "6.0"
    url: "https://learn.unity.com/tutorial/create-dynamic-enemies.md?language=en&version=6.0"
  - name: "6.3"
    url: "https://learn.unity.com/tutorial/create-dynamic-enemies.md?language=en&version=6.3"
last_updated: "2026-08-04T14:21:38.000Z"
---

# Create dynamic enemies 

Create enemies that move through the level and detect the player to increase gameplay challenge.

In this tutorial, you’ll create dynamic enemies that move through the level and also detect the player, making the gameplay more challenging.

## 1. Overview

In this tutorial, you’ll enhance your haunted house level by introducing a new type of dynamic enemy: the **Ghost**. Unlike the static Gargoyle, the Ghost will move through the environment. By the end of this tutorial, you’ll have a roaming enemy that actively patrols the hallways, making the player character’s escape more challenging and immersive.

## 2. Set the Ghost prefab

The first step in setting up your moving enemy is to create a prefab using the **Ghost** model. This will allow you to reuse and edit the Ghost enemy consistently across your scene. Since you’ve already worked with prefabs in previous steps, this process should feel familiar.

We’ve provided two different types of ghosts for you to choose from: an **Eye Ghost** and a **regular Ghost**. Pick the one you like best!

[Video](https://connect-mediagw.unity.com/h1/20250617/videos/11e6c419-7a0e-4c20-b7a6-0d35657d760b_6.2_-_Set_the_Ghost_prefab.mp4)

**1.  Create an empty container for your Ghost character:**

- Right-click in the **Hierarchy** window (or open the **Add** (**+**) dropdown in the upper-left corner) and select **Create Empty**. This will create a new empty GameObject in your scene.
- Rename the empty GameObject “Ghost”.

**2.**  **Add the Ghost to the scene:**

- In the **Project** window, navigate to **\_3DStealthGame** > **Art** > **Models** > **Characters** > **Enemies** and examine the two ghost models (**EyeGhost_model,** **RegularGhost_Model**)
- Drag the **\[Type\]Ghost_Model** of your choice onto the **Ghost** GameObject in the **Hierarchy** window.
- In the **Inspector** window, ensure the **Transform** component of the **\[Type\]Ghost_Model** has its **Position** property set to **X** = **0**, **Y** = **0**, and **Z** = **0**.
- While you work on setting up the **Ghost** properly, place it near the **Player** GameObject using the **Move** Tool. Don’t worry, you’ll position it more accurately later on.

**3.**  **Create a Ghost prefab:**

- From the **Hierarchy** window, drag the **Ghost** GameObject into the **\_3DStealthGame** > **Prefabs** > **Characters** folder in the **Project** window.
- If prompted, select **Original Prefab**.

In the next step you’ll bring the **Ghost** GameObject to life with animations. Let’s make this creepy creature move!

## 3. Animate the Ghost

Now that your **Ghost** prefab is in place, it’s time to bring it to life with animation. The Ghost will have a simple looping walk animation using an Animator Controller,  just like you did with the Gargoyle. This will make the enemy look like it’s actively patrolling the haunted house.

[Video](https://connect-mediagw.unity.com/h1/20250617/videos/939f6fab-1bf6-49e3-a53c-9efbcd3f9395_6.3_-_Animate_the_Ghost.mp4)

**1.**  **Make sure you're in prefab editing mode:**

If you're not in prefab editing mode, double-click the **Ghost** prefab in the **Project** window to enter it.

**2.**  **Create an Animator Controller:**

- In the **Project** window, navigate to **\_3DStealthGame** > **Art** > **Animation** > **Animators**.
- Right-click the **Animators** folder and select **Create** > **Animation** > **Animator Controller**.
- Name the new Animator Controller “Ghost_Controller”.

**3.**  **Set the Animator component:**

- In the **Hierarchy** window, use the foldout (triangle) to expand the **Ghost** GameObject and select the **\[Type\]Ghost_Model** GameObject.
- In the **Inspector** window, locate the **Animator** component.
- Click and drag the **Ghost_Controller** Animator Controller onto the **Animator** component’s **Controller** property box.

**4.**  **Add the walking animation:**

- Double-click the **Ghost_Controller** Animator Controller to open it in the **Animator** window.
- In the **Project** window, navigate to **\_3DStealthGame** > **Art** > **Animation** > **Animations**.

We’ve provided two different walking animations for your ghost; feel free to choose the one you like best.

- Expand the following model assets:
  - **Ghost@Walk1**
  - **Ghost@Walk2**
- Inside each, locate the animation clips named **Walk1** and **Walk2**.
- To preview the animations, select each one. In the **Inspector** window, scroll down to find the **Preview** section, then select the **Play** button to see how it looks.

**Note:** You’ll notice that each animation plays with a different character model. But don’t worry, both Ghost characters share the same skeleton (that does sound a little weird), which basically means they have the same body structure underneath. So the animations are fully compatible and will work perfectly on both models.

- Once you’ve chosen your favorite walking animation, click and drag the **Walk** animation into the **Animator** window.
- Select the **Play** button to enter Play mode and check out your animated **Ghost**.

Your Ghost enemy is now animated and ready to haunt the hallways. In the next step, you’ll add a **Capsule** **Collider** component and a **Rigidbody** component so the **Ghost** can physically interact with the player character.

## 4. Add physics to the Ghost

Just like the player character and the Gargoyles, Ghosts also need a physical presence in the scene to interact properly with other GameObjects. This means they require a collider.

Since Ghosts move, they also need a **Rigidbody** component, but it must be set up carefully: colliding with the **Player** GameObject shouldn’t push the **Ghost** GameObject around.

[Video](https://connect-mediagw.unity.com/h1/20250617/videos/4d1a80f3-a0bd-45ae-ae06-6eee3d597ecd_6.4_-_Add_physics_to_the_Ghost.mp4)

**1.**  **Add a collider:**

- Confirm that you are still in prefab editing mode for the **Ghost prefab**.
- In the **Inspector** window, select the **Add Component** button.
- Search for and add the **Capsule Collider** component.
- Adjust the collider to fit the **Ghost** prefab’s shape; the recommended values are as follows:
  - Set the **Center** property to **X** = **0, Y** =  **0.6**, and **Z** = **0**.
  - Set the **Radius** property to **0.25**.
  - Set the **Height** property to **1.2**.

**2.**  **Add a Rigidbody component:**

- In the **Inspector** window, select the **Add Component** button.
- Search for and add the **Rigidbody** component.
- Enable **Is Kinematic**.

**Note:** A kinematic **Rigidbody** component won’t react to forces like collisions, but it will still be able to detect them.

Your **Ghost** enemy now has boundaries and the ability to interact with other GameObjects in the scene. In the next step, you’ll add the **PointOfView** prefab so that the **Ghost** prefab will be able to detect the **Player** GameObject, just like the **Gargoyle** prefab.

## 5. Make the Ghost an observer

Your **Ghost** prefab looks really cute, but it currently lacks the capacity to detect the **Player** GameObject that the other **Gargoyle** enemy has.

Luckily, you’ve already set up a **PointOfView** prefab for the **Gargoyle** that handles detection. Instead of building it from scratch again, let’s reuse that same prefab and attach it to the **Ghost** prefab.

[Video](https://connect-mediagw.unity.com/h1/20250617/videos/c9fd33bf-1555-43ee-8564-38686570e2e1_6.5_-_Make_the_ghost_an_observer.mp4)

**1.**  **Attach the PointOfView prefab:**

- Confirm that you are still in prefab editing mode for the **Ghost** prefab.
- Drag the **PointOfView** prefab from the **\_3DStealthGame** > **Prefabs** folder onto the **Ghost** GameObject in the **Hierarchy** window.

Now the **Ghost** prefab has its own **PointOfView** and can use the detection system!

**2.**  **Adjust the PointOfView for the Ghost prefab’s height and orientation:**

- In the **Hierarchy** window, select the **PointOfView** GameObject.
- In the **Inspector** window, update the **PointOfView** GameObject’s **Transform** component as follows:
  - **Position property**: **X** = **0**, **Y** = **0.75,** and **Z** = **0.4**.
  - **Rotation property**: **X** = **0**, **Y** = **0**, and **Z** = **0**.

**Note:** We set the **Rotation** property to **X** = **0**, **Y** = **0**, and **Z** = **0** because the **Ghost** GameObject looks forward, unlike the **Gargoyle** GameObject that stands on a podium and needs to look slightly downwards.

**3.**  **Set the Player reference for detection:**

- Exit prefab editing mode to go back to the normal **Scene** view.
- In the **Inspector** window, locate the **Ghost** GameObject’s **Observer** script component and click and drag the **Player** GameObject from the **Hierarchy** window onto the **Player** property box to assign its **Transform** component

**4.**  **Observe the detection:**

- Select the **Play** button to enter Play mode.
- Move the **Player** GameObject into the **Ghost** GameObject's field of vision to see the console message showing it detected the **Player** GameObject, just like the **Gargoyle** GameObject did.

**Note:** Remember to exit Play mode when you’re done testing.

Now your **Ghost** prefab is set up as an **Observer** and can detect the **Player** GameObject. In the next step, you’ll add movement functionality so that the **Ghost** GameObject can dynamically move along a determined path.

## 6. Create the WaypointPatrol script

Now you’re ready to set up the **Ghost** GameObject so it can move through your game environment. You’ll create a script that manages how the **Ghost** moves around the space.

This script uses a simple graph-based approach: you provide a set of points for the **Ghost** to visit, and the script calculates the shortest path between each point in order. It’s a straightforward way to achieve the behavior we want.

However, another common method for dynamic enemy movement in Unity is using Unity’s [**AI Navigation**](https://docs.unity3d.com/Packages/com.unity.ai.navigation@2.0/manual/index.html) package. If you’d like to try that approach instead, head to **Step 4** of the **Bonus Features** tutorial.

Also, if you're curious to understand how the script works, check out [**Step 9**](https://learn.unity.com/tutorial/create-dynamic-enemies#68518f55edbc2a35581ed601), where we explain the key parts in more detail. If you already have some experience, you’re welcome to write your own version of the **WaypointPatrol** script and customize it as you like!

[Video](https://connect-mediagw.unity.com/h1/20250617/videos/45ebcbc9-a3e6-4212-8862-5cb80d7ded99_6.6_-_Create_the_WaypointPatrol_script.mp4)

**1.**  **Create a new script:**

- In the **Project** window, navigate to **\_3DStealthGame** > **Scripts**.
- Right-click the **Scripts** folder.
- Select **Create** > **MonoBehaviour Script**.
- Rename the script “WaypointPatrol” and press **Enter**.

**2.**  **Add the script to the Ghost prefab:**

- In the **Project** window, double-click the **Ghost** prefab to open it in prefab editing mode.
- Select the **Ghost** GameObject and click and drag the **WaypointPatrol** script from the **Project** window into the **Inspector** window to add it as a component.

**3.**  **Open the script:**

- Double-click the newly created **WaypointPatrol** script.
- This will open the script in the code editor or IDE you've set up (such as Visual Studio).

**4.**  **Copy the provided code:**

- Once the script is open, delete any pre-filled content.
- Copy and paste the following lines of code into the script, then save it:

```csharp
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;

public class WaypointPatrol : MonoBehaviour
{
    public float moveSpeed = 1.0f;
    public Transform[] waypoints;

    private Rigidbody m_RigidBody;
    int m_CurrentWaypointIndex;

    void Start ()
    {
        m_RigidBody = GetComponent<Rigidbody>();
    }

    void FixedUpdate ()
    {
        Transform currentWaypoint = waypoints[m_CurrentWaypointIndex];
        Vector3 currentToTarget = currentWaypoint.position - m_RigidBody.position;

        if (currentToTarget.magnitude < 0.1f)
        {
            m_CurrentWaypointIndex = (m_CurrentWaypointIndex + 1) % waypoints.Length;
        }
        Quaternion forwardRotation = Quaternion.LookRotation(currentToTarget);
        m_RigidBody.MoveRotation(forwardRotation);
        m_RigidBody.MovePosition(m_RigidBody.position + currentToTarget.normalized * moveSpeed * Time.deltaTime);
    }
}
```

## 7. Place Ghosts in your scene

Now you’re ready to bring your haunted environment to life by populating it with moving enemies. In this step, you’ll duplicate the **Ghost** GameObject and place enemies throughout the level. Each **Ghost** GameObject should be positioned in a way that creates unique challenges for the player, such as patrolling corridors, guarding important areas, or restricting movement near exits. These **Ghost** GameObjects will form the foundation for your enemy patrol behavior.

[Video](https://connect-mediagw.unity.com/h1/20250617/videos/303c7ae9-752d-4b76-a5a4-8c96ec1474c4_6.7_-_Place_Ghosts_in_your_Scene.mp4)

**1.**  **Decide how many Ghost GameObjects you want:**

Before you add any **Ghost** GameObjects, take a moment to analyze your level and think about how each ghost can enhance gameplay and increase difficulty. Here are a few suggestions:

- Place a one to patrol near the player’s starting room
- Add one in a long corridor to encourage the player to use side rooms for cover
- Use another to circle around a central object, like a dining room table
- Have one patrol near the level’s exit to create tension during the final stretch.

Once you have an idea of where ghosts would be most effective, move on to the next steps.

**2.**  **Duplicate the Ghost GameObject:**

- In the **Hierarchy** window, select the original **Ghost** GameObject.
- Press **Ctrl**+**D** (macOS: **Cmd**+**D**) to duplicate it.
- Repeat this process to create as many ghosts as you want in the scene.

**3.**  **Position each ghost in the level:**

- Use the **Move/Rotate Tools** to place each **Ghost** GameObject in its designated area.

Remember, try to place the ghosts where their patrols will naturally block or complicate the player’s movement; this will make for a more interesting challenge!

**4.**  **Organize ghosts inside the Enemies GameObject:**

- In the **Hierarchy** window, locate the **Enemies** parent GameObject you created in the last tutorial.
- Hold the **Shift** key, select all the **Ghost** GameObjects you created, and drag them inside the **Enemies** GameObject to set them as child GameObjects.

With all ghosts placed and enemies organized, your level now has enemies that increase tension and gameplay complexity. In the next step, you’ll create and assign waypoints so that each ghost can move around its patrol path.

## 8. Create and position the ghost waypoints

To guide each ghost along a patrol path, you’ll use empty GameObjects as waypoints. Since you only need their **Transform** positions, there’s no need for visual components.

In this step, you’ll create and organize all the waypoints first, then assign two or more to each **Ghost** GameObject based on where you placed them in the previous step. This modular approach allows each ghost to follow a unique path, increasing variety in enemy behavior.

[Video](https://connect-mediagw.unity.com/h1/20250617/videos/f3ba382c-4261-4ab1-a5ab-ef84c1d5acee_6.8_-_Create_and_Position_the_Ghost_Waypoints.mp4)

**1.**  **Create a patrol path for the first ghost:**

Before you place any waypoints, take a moment to decide how you want this ghost to patrol.

- Will it move between two points, like a short hallway patrol?
- Will it follow a more complex route, like circling a room or weaving through multiple spaces?

Once you have a path in mind:

- Right-click in the **Hierarchy** window and select **Create Empty**.
- Rename the empty GameObject “Waypoint_1_Start”.

**Note:** For better visibility, switch to a top-down view by clicking the **Y** axis on the **Scene Gizmo**, located  at the top-right corner of the **Scene** view**.**

- Position the **Waypoint_1_Start** GameObject at the beginning of the first ghost’s patrol path.
- Press **Ctrl**+**D** (macOS: **Cmd**+**D**) to duplicate and create more waypoints.
- After each duplication, rename each waypoint sequentially (**Waypoint_1_End**, **Waypoint_1_Mid**, etc.) and move them to follow your chosen path.

There’s no required number of waypoints, just add enough to define the route you want. Each waypoint represents a step in the ghost’s journey.

**2.**  **Make waypoints visible in the Scene view:**

By default, empty GameObjects can be hard to see. To make them easier to spot:

- Select all the **Waypoint** GameObjects you just created in the last step.
- In the **Inspector** window, select the cube icon in the upper-left corner.
- Choose a colored icon from the dropdown menu (for example, a red or blue label).

This will help you visualize paths clearly in the **Scene** view as you build your level.

**3.**  **Assign waypoints to the first Ghost GameObject:**

- Select the first **Ghost** GameObject in the **Hierarchy** window.
- In the **Inspector** window, select the **Add** **Component** button.
- Search for and add the **Waypoint Patrol** component.
- Select the **Add** (**+**) button to add as many **Waypoint** slots as you defined.
- Click and drag the corresponding waypoints (like **Waypoint_1_Start**, **Waypoint_1_End**) into each box.

**4.**  **Create more paths for the other ghosts in your scene:**

- Repeat Steps 1–3 for the remaining **Ghost** GameObjects.

Give each one its own waypoints and path, adjusting the number and layout to fit your level’s design.

**5.**  **Organize waypoints inside a parent GameObject:**

- Hold **Shift** and select all the waypoints, then right-click on them and choose **Create Empty Parent.**
- Rename the new parent GameObject “Waypoints”.
- Reset its **Transform** position to (**X** = **0**, **Y** = **0**, and **Z** = **0**).

**6.** **Test the patrol paths:**

- Enter Play mode and observe the ghosts in action.
- Watch their movement to verify they follow the correct path.

Each **Ghost** GameObject now has its own patrol path! With that, you've set up all the core gameplay functionality. In the next tutorial, you’ll add a **UI** to give players visual feedback when they get caught or escape, and you’ll also complete the game-ending loop.

## 9. Review the WayPointPatrol script

This step is completely optional, but if you’re curious about how the **WayPointPatrol** script works, here are a few parts of the code you might find especially interesting.

**1.**  **Main patrol logic:**

```csharp
void FixedUpdate ()
{
    Transform currentWaypoint = waypoints[m_CurrentWaypointIndex];
    Vector3 currentToTarget = currentWaypoint.position - m_RigidBody.position;
```

- Calculates the direction vector from the current position to the target waypoint.
- Similarly, when the player character exits the trigger area, it sets the flag back to **false**.

**2.**  **Waypoint switching:**

```csharp
if (currentToTarget.magnitude < 0.1f)
{
    m_CurrentWaypointIndex = (m_CurrentWaypointIndex + 1) % waypoints.Length;
}
```

- If the GameObject is close enough to the current waypoint, it switches to the next waypoint in the list.
- Uses **modulo** (**%**) to loop back to the first waypoint after the last one.

**3.**  **Moving toward waypoint:**

```csharp
Quaternion forwardRotation = Quaternion.LookRotation(currentToTarget);
m_RigidBody.MoveRotation(forwardRotation);

m_RigidBody.MovePosition(m_RigidBody.position + currentToTarget.normalized * moveSpeed * Time.deltaTime);
```

- Instantly rotates the GameObject to face the direction of the next waypoint.
- Moves the GameObject in the direction of the waypoint at a constant speed, frame-rate independent.

If you’d like to dive deeper into programming, we recommend checking out the [**Junior Programmer Pathway**](https://learn.unity.com/pathway/junior-programmer), where you’ll learn the fundamentals of coding in Unity.

## 10. Next steps

With these steps completed, you’ve implemented a dynamic enemy that can catch the player character while patrolling an area.

In the next tutorial, you’ll define the game ending conditions, set up a simple UI, and create a basic game loop for the game.
