Melee & Projectile System

Enemy Masses includes a highly optimized combat system designed specifically for large-scale battles involving thousands of units. Unlike standard Unity solutions that rely on heavy GameObjects and Physics Colliders for every bullet or sword swing, this system uses lightweight data structures and GPU instancing to maintain high frame rates.

Overview

  • Performance First: Projectiles are not GameObjects. They are lightweight data entities managed by a central system.

  • Per-Faction Configuration: All combat settings are defined in the EnemyCrowd ScriptableObject.

  • VFX Graph Support: Fully integrated with Unity's VFX Graph for massive particle counts.

  • Audio Instancing: Smart audio management prevents thousands of simultaneous sounds from overwhelming the audio engine.


Configuration

To configure combat for a faction:

  1. Select your EnemyCrowd asset.

  2. Navigate to the Combat tab in the inspector.

  3. Choose your Attack Type: Melee or Ranged.

Melee Configuration

The Melee system handles close-quarters combat. It is designed to sync damage events with your unit's animations.

Setting
Description

Damage

The amount of damage dealt per hit.

Attack Range

The maximum distance at which a unit can strike a target.

Attack Rate

How many seconds between attacks.

Hit Delay

The delay (in seconds) from the start of the attack animation to the moment damage is dealt. Adjust this to match the "impact" frame of your animation.

Hit VFX

Visual effect spawned at the impact point (supports ParticleSystem or VFX Graph).

Hit Sound

Audio clip played on impact, with pitch variation and spatial blending settings.

Projectile Configuration

The Projectile system handles ranged attacks, from arrows and bullets to magic missiles and grenades.

Trajectory Types

  • Linear: Moves in a straight line (Arrows, Bullets, Magic Bolts).

  • Parabolic: Arcs through the air affected by gravity (Grenades, Mortars, Catapults).

  • Hitscan: Instant travel time (Lasers, Sniper Rifles).

Spawning Projectiles

You can define exactly where projectiles appear relative to the unit:

  • Offset: Simple Vector3 offset from the unit's root.

  • Transform: Reference a specific Transform in the prefab (e.g., a "Muzzle" object).

  • Bone Path/Name: Find a bone by name or hierarchy path (useful if you don't want to modify the prefab).

Visuals & VFX

Since projectiles are not GameObjects, their visuals are handled efficiently:

  • Mesh & Material: Renders the projectile using GPU Instancing (e.g., an arrow mesh).

  • VFX Graph: Can attach a VFX Graph to the projectile for trails or magic effects.

  • Muzzle Flash: Spawns a visual effect at the firing point.

  • Impact VFX: Spawns a visual effect when the projectile hits a target or the ground.

Advanced Features

  • Homing: Projectiles can steer towards their target (great for magic missiles).

  • Piercing: Projectiles can pass through multiple enemies (e.g., a railgun or ballista bolt).

  • AOE (Area of Effect): Explodes on impact, dealing damage in a radius with falloff.

Hitscan (Lasers)

For instant attacks like lasers, the system uses a specialized renderer.

  • Beam Width: Thickness of the laser beam.

  • Duration: How long the beam remains visible.

  • Texture Scrolling: Animate the beam texture for a flowing energy effect.

  • Color: Tint the beam color.


Performance & Optimization

This system is built to solve the "1000 unit problem".

  1. No Colliders: Projectiles do not use Unity Physics. They use a custom spatial hashing system to detect hits efficiently.

  2. No GameObjects: A fired arrow does not instantiate a new GameObject. It is a struct in a managed array.

  3. Batching: All projectiles of the same type are drawn in a single draw call using DrawMeshInstanced.

  4. Audio Culling: If 500 units fire at once, the system intelligently plays only a subset of sounds to prevent audio artifacts and CPU spikes.

Last updated