Unity logo
Cancel
Cart
Applications
Sell Assets

Over 11,000 five-star assets

Rated by 85,000+ customers

Supported by 100,000+ forum members

Every asset moderated by Unity

Home
Templates
Systems
1/8
This my Easy To Use Battle System for any game to trying to make
Render pipeline compatibility
The Built-in Render Pipeline is Unity’s default render pipeline. It is a general-purpose render pipeline that has limited options for customization. The Universal Render Pipeline (URP) is a Scriptable Render Pipeline that is quick and easy to customize, and lets you create optimized graphics across a wide range of platforms. The High Definition Render Pipeline (HDRP) is a Scriptable Render Pipeline that lets you create cutting-edge, high-fidelity graphics on high-end platforms.
Unity VersionBuilt-inURPHDRP
2022.3.18f1
Compatible
Compatible
Compatible
Description

This a Battle System Solution is a very modular system, and very easy to use as well as understandable, customizable and very easy to use for beginners and would be very simple to use for expert and intermediate programmers like me.


I created this very Battle System for my Game MechVania, which I Published on Itch.io:

https://mattjgames.itch.io/mechvania.


Technical details

Battle System Details:


1. Battle States: Defining the Flow of Combat

The main flow control for this battle system is an enumeration called BattleState, with three states:

  • Idle: The initial, non-active state. Here, the battle is not started, and no waves or enemies are active.
  • Active: Once the battle begins, it moves into this state, where waves and enemies spawn and fight against the player.
  • Finished: This state signals the end of the battle, triggered when all waves are completed and no more enemies are left.

The variable currentState is used to track which state the battle is currently in, ensuring smooth transitions through the phases of combat.


2. Battle Start and Wave Initialization

When the player initiates combat, the StartBattle method is called:

  • The battle begins only if currentState is Idle.
  • The method switches currentState to Active and starts the first wave by calling StartNextWave.
  • This ensures that the battle only begins once and progresses in an orderly fashion through each wave.

Each wave is handled by an instance of the Wave class, which contains an array of Enemy Spawners. This wave-based approach allows for organized and escalating enemy encounters, as each wave is managed individually.



3. Wave Management: Starting and Updating Waves

In the Update method:

  • While in the Active state, the system checks the currentWaveIndex, which tracks the progression of waves.
  • If currentWaveIndex is less than the total number of waves, the current wave is accessed and updated continuously through UpdateWave().
  • This allows each active wave to spawn and update its enemies in real-time, maintaining active engagement until the wave is completed.

The wave progression is handled by StartNextWave, incrementing currentWaveIndex and initiating the subsequent wave’s spawners, which introduce new challenges to the player. If currentWaveIndex exceeds the total number of waves, it calls EndBattle, concluding the combat.



4. Ending the Battle

When all waves have been completed:

  • EndBattle sets currentState to Finished.
  • This triggers onBattleEnd, a UnityEvent that can be used to notify other game systems or trigger UI changes, like displaying a victory message.

Additionally, a log entry (Debug.Log("Battle Finished")) indicates the end of the battle for debugging or testing purposes.



5. Wave Class: Controlling Enemy Spawners

The Wave class contains:

  • An array of Enemy Spawners, each responsible for managing a portion of the enemies.
  • A series of methods, StartWave, UpdateWave, and IsWaveOver, that regulate the spawning and completion of each wave.

- Starting and Updating a Wave

When StartWave is called, it iterates over each spawner in spawners, calling StartSpawning() to initiate enemy creation. During the wave, UpdateWave() continuously calls UpdateSpawning() on each spawner, keeping enemies active and their states up-to-date.

- Wave Completion Check

The method IsWaveOver() checks if all enemies within the wave have been defeated:

  • It iterates over each spawner in spawners, checking if AreAllEnemiesDead() returns true.
  • If any spawner still has active enemies, IsWaveOver() returns false, indicating the wave is not yet over.
  • Once all spawners confirm that their enemies are defeated, IsWaveOver() returns true, signaling that the wave is complete and allowing the battle system to proceed to the next wave.


6. Modular Design for Flexibility and Expansion

This battle system is designed with modularity, allowing easy adjustment or expansion:

  • Waves and Enemy Spawners: Each wave is independently defined, enabling developers to customize waves or add more by simply increasing the waves array.
  • State-driven Control: Using BattleState to manage the flow ensures that transitions are predictable and controlled, allowing for additional states or conditions if needed.
  • Unity Events: The onBattleEnd event allows developers to extend functionality at the battle’s conclusion, such as initiating new events, UI transitions, or rewards for the player

Summary of Key Features

  • Battle Flow Control through BattleState (Idle, Active, Finished)
  • Wave-based Combat System managed by Wave and EnemySpawner classes
  • Real-time Wave Updates and progression tracking with UpdateWave and IsWaveOver
  • Modular and Extendable Design for ease of customization and potential expansion

Enemy Spawner Details:


1. Key Variables: Controlling Spawning Behavior

The script’s core functionality revolves around several key variables:

  • enemyPrefab: Holds the prefab for the enemy to spawn, serving as a template for all enemies generated by this spawner. This allows you to assign different enemy types to different spawners for varied gameplay.
  • spawnPoint: The location from which enemies are spawned, initialized to the spawner’s transform in Start(). This can be modified to spawn enemies at a specific point or position in the game environment.
  • enemiesToSpawn: Specifies the total number of enemies that this spawner should create in one cycle. As enemies are spawned, this count decreases until it reaches zero, at which point spawning concludes.
  • spawnDelay: Sets the delay (in seconds) between each enemy spawn, allowing for gradual enemy appearance rather than spawning all at once. This staggered spawning contributes to a more engaging combat flow.
  • spawnedEnemies: A list that stores references to each enemy spawned by this spawner. It allows tracking of the enemies' status, enabling cleanup and completion checks as the enemies are defeated or removed.

2. Start Method: Initial Setup

The Start() method initializes the spawnPoint to the object’s own transform if not set otherwise. This default behavior simplifies setup by allowing the spawner to use its own location unless directed to a different spawn point. It makes the script versatile and reduces the need for specific configuration unless explicitly desired.


3. Starting Spawning: StartSpawning Method

When StartSpawning() is called, the spawner becomes active, preparing it to spawn enemies:

  • Activates Spawning: Sets spawningActive to true, allowing the spawner to begin generating enemies when UpdateSpawning() is called.
  • Resets the Timer: Initializes spawnTimer to spawnDelay, ensuring that the delay timing starts fresh each time spawning begins.

This method provides flexibility, as it allows external scripts (such as the Wave manager) to control when the spawner becomes active, enabling precise control over wave timing and pacing.


4. Update Method: Managing the Spawn Cycle with UpdateSpawning

The UpdateSpawning() method controls the timing and conditions for enemy spawning, executing as long as spawning is active and enemies remain to be spawned:

  • Decrements the Timer: The spawnTimer is reduced by Time.deltaTime on each frame, creating a countdown between enemy spawns.
  • Spawns on Timer: When spawnTimer reaches zero, SpawnEnemy() is called, which creates a new enemy at the specified spawn point.
  • Resets the Timer: After each spawn, spawnTimer is reset to spawnDelay, creating a consistent delay between enemy appearances.

This timing mechanism allows for a staggered spawn effect, avoiding overwhelming the player with a flood of enemies. Instead, it delivers a steady flow, increasing the intensity and pacing of the gameplay.


5. Enemy Creation: SpawnEnemy Method

The SpawnEnemy() method generates a new enemy instance:

  • Instantiates Enemy: A new enemy is instantiated using Instantiate(), based on the enemyPrefab, and placed at spawnPoint.position with spawnPoint.rotation.
  • Tracks Spawned Enemies: Each spawned enemy is added to the spawnedEnemies list for tracking purposes. This list is crucial for determining which enemies remain active and for managing the cleanup of defeated enemies.
  • Decreases Enemy Count: enemiesToSpawn is decremented by 1 after each spawn. When enemiesToSpawn reaches zero, no more enemies are created, signaling that the spawner has fulfilled its quota.

This method gives precise control over each individual enemy's creation, allowing for on-the-fly customization and control over where and how each enemy enters the game.


6. Enemy Tracking and Completion Check: AreAllEnemiesDead Method

The AreAllEnemiesDead() method provides a way to determine if all spawned enemies have been defeated:

  • Cleans Up Null Entries: Any null entries (destroyed or defeated enemies) are removed from spawnedEnemies using RemoveAll. This ensures that only active enemies are considered in the list, keeping memory usage efficient and enabling accurate tracking.
  • Checks Enemy Count: Returns true if both spawnedEnemies is empty and enemiesToSpawn is zero. This condition indicates that all intended enemies have been spawned and subsequently defeated, signaling that the wave is complete.

This completion check is crucial for managing wave progression, as it enables the wave manager to confirm the spawner’s job is done and transition to the next wave or trigger end-of-wave actions.


7. Modular and Adaptable Design

The structure of this Enemy Spawner script is highly modular and adaptable, with several design choices that make it easy to reuse and customize:

  • Customizable Spawn Points: You can assign specific spawn points to each spawner, giving flexibility to control enemy entry points and adjust them for different levels or battle arenas.
  • Adjustable Spawn Delay and Count: With spawnDelay and enemiesToSpawn, developers can control the rate and volume of enemies for each spawner, enabling tailored pacing for each wave or level.
  • Tracking and Cleanup: By keeping a spawnedEnemies list and a clean-up function, the script ensures efficient memory use and allows precise tracking of enemy status, helping to prevent performance issues as the game progresses.

Modular Battle System

(not enough ratings)
$7
Taxes/VAT calculated at checkout
License type: Single Entity
Single Entity
Recommended for individuals and small businesses.
Multi Entity
Recommended for large enterprises working across multiple locations.
Refund policy
This asset is covered by the Unity Asset Store Refund Policy. Please see section 2.9.3 of the EULA for details.
Secure checkout:
Supported payment methods: Visa, Mastercard, Maestro, Paypal, Amex
License type
File size
666.6 KB
Latest version
1.0
Latest release date
Nov 21, 2024
Original Unity version
2022.3.18
Quality assets
Over 11,000 five-star assets
Trusted
Rated by 85,000+ customers
Community support
Supported by 100,000+ forum members
Unity logo
Language
Feedback
Partners Program
Partners
USD
EUR
Copyright © 2025 Unity Technologies
All prices are exclusive of tax
USD
EUR