In this tutorial, you’ll build a simple enemy spawning system in Unity. When the player enters a trigger, enemies appear at designated spawn points. The player can remove them by touching them, and the trigger keeps spawning enemies until it reaches a specified total.

What you will build in this tutorial

Prerequisites

  • Unity 6.6 (6000.6.8f1)
  • Basic familiarity with the Unity Editor (Hierarchy, Inspector, and Project windows)
  • The free First Person + Third Person | Character Controllers package (also known as the Starter Assets) from Unity Technologies

Set up the project

  1. Create a new project

    In Unity Hub, create a new project and choose the Universal 3D template.

    Unity Hub New project screen with the Universal 3D template selected

  2. Check the empty project

    This is what an empty project looks like.

    Empty Universal 3D project open in the Unity Editor

Add a floor

  1. Create a plane

    Go to GameObject > 3D Object > Plane.

    GameObject menu with 3D Object > Plane selected

  2. Reset the transform

    In the Inspector, right-click the Transform header and choose Reset. This puts the floor at the origin.

    Transform context menu in the Inspector with Reset highlighted

  3. Enlarge the floor

    Set the Scale to (5, 1, 5). A Unity plane is 10 × 10 meters by default, so this gives you a 50 × 50 meter floor.

    Transform Scale set to 5, 1, 5

Import the Starter Assets

  1. Open the Asset Store tab

    Click the Asset Store tab to activate it.

    Asset Store tab in the Unity Editor

  2. Go to the Asset Store website

    Click Search online to open the Asset Store.

    Search online button in the Asset Store tab

  3. Search for the Starter Assets

    Enter Starter Assets Third Person in the search bar at the top, then click the magnifying glass icon.

    Asset Store search bar with Starter Assets Third Person entered

  4. Select the package

    Click First Person + Third Person | Character Controllers from Unity Technologies.

    Search results with First Person + Third Person | Character Controllers from Unity Technologies highlighted

  5. Add it to your assets

    Click Add to My Assets.

    Add to My Assets button on the First Person + Third Person | Character Controllers page

  6. Open the Package Manager

    Back in Unity, open the Package Manager with Window > Package Management > Package Manager.

    Window menu with Package Management > Package Manager selected

  7. Download the package

    Under My Assets, select First Person + Third Person | Character Controllers and click Download.

    Package Manager showing First Person + Third Person | Character Controllers with the Download button

  8. Import the package

    When the download finishes, click Import 2.0.2 to project. Your version number may differ.

    Package Manager showing the Import 2.0.2 to project button

  9. Confirm the files

    In the Import Unity Package window, leave everything checked and click Import.

    Import Unity Package window listing the files in the Starter Assets folder

  10. Install the dependencies

    When asked to install or upgrade dependencies, click Install/Upgrade. If Unity asks to restart the editor, click Yes.

    Dialog asking to install or upgrade the package dependencies

Add the player

  1. Open the Prefabs folder

    In the Project window, go to Assets/Starter Assets/Runtime/ThirdPersonController/Prefabs.

    Prefabs folder showing the six Starter Assets prefabs

  2. Drag the player into the scene

    Drag NestedParentArmature_Unpack from the Project window into the Hierarchy.

    Hierarchy with NestedParentArmature_Unpack added

  3. Delete the original Main Camera

    Select the Main Camera that came with the template, the one at the top of the Hierarchy, and press Delete or select Delete from the right-click menu. The prefab brings its own camera, and two cameras would conflict.

    Right-click menu on the original Main Camera with Delete selected

  4. Select the player

    In the Hierarchy, click the arrow next to NestedParentArmature_Unpack to expand it, then select PlayerArmature.

    Expanded NestedParentArmature_Unpack with PlayerArmature selected

  5. Center the player

    In the Inspector, set its Position to (0, 0, 0).

    PlayerArmature Transform with Position set to 0, 0, 0

    The parent object is a container that groups the player and its cameras. The character itself is PlayerArmature, so that’s the object to position.

  6. Test the player

    Click the Game tab, then press Play. Use WASD to move, the mouse to look around, Space to jump, and Shift to sprint.

    Play button in the Unity toolbar

    If you click inside the Game view, the mouse cursor is hidden and locked. Press Esc to get it back.

    Third-person character walking, turning, and jumping on the floor

    If the character falls through the floor, stop Play mode and set the Y position of PlayerArmature to 0.1.

  7. Save the scene

    While the game runs, the Play button becomes a Stop button. Click it to stop the game, then press Ctrl + S to save the scene. Changes made during Play mode are lost when you stop, so make any adjustments after you exit.

    Play button highlighted as Stop while the game is running

Create the enemy

  1. Make folders for your files

    Make a SpawnTutorial folder with Materials, Prefabs, and Scripts inside to keep your work separate from the Starter Assets.

    SpawnTutorial folder containing Materials, Prefabs, and Scripts

  2. Create the capsule

    First you create the enemy in the scene. Later, you turn it into a prefab.

    1. Go to GameObject > 3D Object > Capsule to create a capsule for the enemy. A white capsule appears in the Scene view and in the Hierarchy as Capsule.
    2. Rename it to Enemy.

      Renamed the capsule to Enemy

  3. Make the enemy red

    Give the enemy a simple red material to mark it as hostile.

    1. In the Project window, open SpawnTutorial/Materials.
    2. Right-click in the empty area and choose Create > Material. In some Unity 6 versions, it’s under Create > Rendering > Material.
    3. Rename it EnemyRed.

      Renamed the material to EnemyRed

    4. With EnemyRed selected, find Base Map in the Inspector. It has a small color box on the right.

      Base Map property with its color box on the right

    5. Click the color box and pick red. You can type FF0000 into the Hexadecimal field for pure red, or choose a slightly darker red like CC0000, which looks less harsh under lighting.

      Color picker with red selected

    6. Close the color picker.

    7. Apply the material to the capsule.

      Drag EnemyRed from the Project window onto the capsule, either in the Scene view or on Enemy in the Hierarchy. The capsule turns red.

      The capsule may sit partly in the floor. That's fine, since spawned enemies get their position from spawn points.

      The enemy capsule after the material has been applied

  4. Make the collider a trigger

    A normal collider is solid, so the player would bump into the capsule. A trigger collider lets the player walk into it, and Unity sends an OnTriggerEnter message that your script will use to remove the enemy.

    1. Select Enemy in the Hierarchy.
    2. In the Capsule Collider component, check Is Trigger.

      Capsule Collider with Is Trigger checked

  5. Turn it into a prefab

    A prefab is a reusable template saved in your project. The spawner will create copies of it at runtime, so the enemy in the scene is no longer needed once the prefab exists.

    1. Drag Enemy from the Hierarchy into the SpawnTutorial/Prefabs folder in the Project window.

      Enemy prefab in the SpawnTutorial/Prefabs folder

    2. Select Enemy in the Hierarchy and press Delete.

  6. Check the player's tag

    The Enemy script identifies the player by its tag, so PlayerArmature needs the Player tag. The Starter Assets already set this tag, but it’s worth confirming.

    1. Select PlayerArmature in the Hierarchy.
    2. In the Inspector, confirm Tag is set to Player. If it isn't, choose Player from the drop-down.

      PlayerArmature Inspector with Tag set to Player

  7. Create the Enemy script

    The enemy removes itself when the player touches it. Keeping this logic on the enemy means you don't have to modify the Starter Assets player.

    1. In SpawnTutorial/Scripts, right-click and choose Create > Scripting > MonoBehaviour Script. Name it Enemy.
    2. Double-click Enemy to open it in your code editor, and replace its contents with this code:

      using UnityEngine; public class Enemy : MonoBehaviour { private void OnTriggerEnter(Collider other) { if (other.CompareTag("Player")) { Destroy(gameObject); } } } 

      Save the file and switch back to Unity. Unity recompiles the script automatically.

    3. Select the Enemy prefab in SpawnTutorial/Prefabs. In the Inspector, click Add Component and choose Enemy.

      Enemy prefab Inspector with the Enemy script component added

    How it works:

- Unity calls `OnTriggerEnter` when another collider enters the enemy's trigger. The player's Character Controller counts as a collider, so no Rigidbody is needed. - `CompareTag("Player")` checks whether the object that entered is the player. It's faster than comparing `other.tag == "Player"`. - `Destroy(gameObject)` removes the whole enemy. Writing `Destroy(this)` instead would remove only the script and leave the capsule in the scene. 
  1. Test the enemy

    1. Drag the Enemy prefab into the Scene view a few meters in front of the player. Unity places it on the floor.
    2. Press Play and walk into the capsule. It disappears.
    3. Stop Play mode and delete the test enemy from the scene.

      Player walking into the red capsule, which disappears

Create the spawn trigger

The spawn trigger is a box marked by a see-through orange visual. When the player walks into it, the box disappears and enemies spawn at a set of spawn points, keeping no more than a set number alive at once until the trigger has spawned its total.

  1. Create the SpawnGroupTrigger script

    1. In SpawnTutorial/Scripts, create a new MonoBehaviour Script named SpawnGroupTrigger.
    2. Double-click it to open it in your code editor, and replace its contents with this code:

      using System.Collections.Generic; using UnityEngine; using UnityEngine.Events; [RequireComponent(typeof(BoxCollider))] public class SpawnGroupTrigger : MonoBehaviour { [SerializeField] private GameObject enemyPrefab; [SerializeField] private Transform[] spawnPoints; [SerializeField, Min(1)] private int totalToSpawn = 6; [SerializeField, Min(1)] private int maxAlive = 3; [SerializeField, Min(0f)] private float minDistanceFromPlayer = 3f; [SerializeField] private bool disableAfterUse = true; [SerializeField] private UnityEvent onTriggered; private readonly List<GameObject> aliveEnemies = new List<GameObject>(); private Transform player; private int spawnedCount; private bool isSpawning; private bool hasTriggered; // Called when the component is first added. Makes the box a trigger automatically. private void Reset() { GetComponent<BoxCollider>().isTrigger = true; } private void OnTriggerEnter(Collider other) { if (!other.CompareTag("Player")) return; if (isSpawning) return; if (disableAfterUse && hasTriggered) return; if (enemyPrefab == null || spawnPoints == null || spawnPoints.Length == 0) { Debug.LogWarning($"{name}: assign an enemy prefab and at least one spawn point.", this); return; } player = other.transform; hasTriggered = true; isSpawning = true; spawnedCount = 0; onTriggered?.Invoke(); } private void Update() { if (!isSpawning) return; // Destroyed objects compare equal to null in Unity, so this drops enemies the player removed. aliveEnemies.RemoveAll(enemy => enemy == null); while (aliveEnemies.Count < maxAlive && spawnedCount < totalToSpawn) { Transform point = FindFreeSpawnPoint(); if (point == null) break; // No usable point right now. Try again next frame. SpawnEnemy(point); } if (spawnedCount >= totalToSpawn) { isSpawning = false; } } // Returns a spawn point that has no enemy on it and isn't too close to the player. private Transform FindFreeSpawnPoint() { for (int i = 0; i < spawnPoints.Length; i++) { // Start at a different point each time so enemies spread out. Transform point = spawnPoints[(spawnedCount + i) % spawnPoints.Length]; if (point == null) continue; if (player != null && Vector3.Distance(point.position, player.position) < minDistanceFromPlayer) continue; if (IsOccupied(point)) continue; return point; } return null; } private bool IsOccupied(Transform point) { foreach (GameObject enemy in aliveEnemies) { if (enemy != null && Vector3.Distance(enemy.transform.position, point.position) < 0.5f) { return true; } } return false; } private void SpawnEnemy(Transform point) { GameObject enemy = Instantiate(enemyPrefab, point.position, point.rotation); aliveEnemies.Add(enemy); spawnedCount++; } // Draws the trigger box and spawn points in the Scene view so you can see them while editing. private void OnDrawGizmos() { BoxCollider box = GetComponent<BoxCollider>(); if (box != null) { Gizmos.color = new Color(1f, 0.6f, 0f); Gizmos.matrix = transform.localToWorldMatrix; Gizmos.DrawWireCube(box.center, box.size); Gizmos.matrix = Matrix4x4.identity; } if (spawnPoints == null) return; Gizmos.color = Color.red; foreach (Transform point in spawnPoints) { if (point == null) continue; Gizmos.DrawSphere(point.position, 0.3f); Gizmos.DrawLine(transform.position, point.position); } } } 

      Save the file and switch back to Unity.

    How it works:

- **Settings:** `[SerializeField]` makes each private field editable in the Inspector. `[Min(1)]` stops the Inspector from accepting zero or negative counts. - **`Reset`:** Unity calls this when the component is first added. It checks **Is Trigger** on the Box Collider for you, and `[RequireComponent]` makes sure the Box Collider exists. - **`OnTriggerEnter`:** starts spawning when the player enters. It ignores every...
Source:https://dev.to/dalanchoo/how-to-build-an-enemy-spawn-trigger-in-unity-c-5ec1