A production-grade, highly-optimized 3D Swarm Intelligence and Formation Navigation System built for Unity. By leveraging the C# Job System, the Burst Compiler, and a custom Spatial Hashing Grid, this framework schedules and executes flocking behaviors, collision avoidance, and tactical formations in parallel across worker threads, maintaining a smooth 60+ FPS with hundreds of active agents.
Designed as a modular, decoupled framework, it represents an industry-standard implementation of scalable agent AI suitable for flight simulators, space shooters, sci-fi RTS, and action games.
ποΈ Architectural Overview Β Β·Β π Key Features Β Β·Β π οΈ Tech Stack & Dependencies Β Β·Β π Project Structure
The system is built on a decoupled, event-driven architecture using high-performance Native Containers and parallel Job pipelines.
graph TD
SC[SwarmController] -->|Orchestrates| FM[FormationManager]
SC -->|Tracks Target| PT[PlayerTarget]
FM -->|Calculates Slots| FS[FlockingSystem]
FS -->|Prepares Native Arrays| SH[Spatial Hash Grid]
FS -->|Schedules Parallel Jobs| FJ[FlockingJob / ObstacleAvoidanceJob]
FJ -->|Parallel Thread Execution| BC[Burst Compiler]
BC -->|Transforms Applied| FE[FlyingEnemy Agents]
FE -->|Modular AI Logic| FSM[FlyingAIStateMachine]
FE -->|Optimizes Behavior & Render| LOD[FlyingEnemyLOD]
FE -->|Triggers Decoupled Events| EH[FlyingAIEvents Hub]
EH -->|Listens & Records| WST[WaveStatsTracker]
-
Vectorized Calculations: Computes classic Boids behaviors (Cohesion, Separation, Alignment) in parallel using
Unity.Mathematics(float3) for maximum SIMD efficiency. -
Spatial Hashing Grid: Replaces standard
$O(N^2)$ distance checks with a custom$O(N)$ 3D Spatial Grid hashing, grouping agents by cell hash map (NativeParallelHashMap) to dramatically reduce neighbor-lookup cost. -
Dynamic Obstacle Avoidance: Integrates jobified raycasting (
RaycastCommand) to calculate dynamic steering corrections around static and moving obstacles in parallel.
- Interface Segregation: Formations are decoupled via the
IFormationinterface and created dynamically using the Factory Pattern (FormationFactory). - Runtime Reconstitution: Instantly calculates slot positioning for V-Shape (Geese), Circle (Surrounding), Grid (Assault), Diamond (Defense), and Line (Pursuit).
- Dynamic Slot Healing: Re-evaluates and fills slots automatically in real-time when squad members are destroyed.
- State Interface Design: Agents utilize a modular State Pattern (
IStateMachine,IState) managing behaviors including Idle, Patrol, Chase, Attack, Evade (Advanced Evasion), and Regroup. - Predictive Chase: Intercepts moving targets using projectile velocity and target velocity vectors to calculate optimal leading intercept vectors.
- Zero GC Allocation: Standard gameplay loop produces 0 bytes of Garbage Collector allocations through custom object pooling (
ObjectPoolBase) for both enemies and projectiles. - Dynamic LOD System: A distance-based Level of Detail (
FlyingEnemyLOD) decreases physics calculations, state updates, and animation cycles for distant swarm agents. - Zero-Overhead Logging: A custom categorized logger (
DebugLogger) utilizing[Conditional]compiler attributes, stripping all log footprints in release/production builds.
- Unity Editor Log Manager: An custom editor window (
LogManagerWindow, shortcutCtrl+Shift+L) featuring category filtering, colored console log outputs, and one-click clipboard exporters to capture diagnostic reports instantly.
- Unity Engine (Recommended: 2022.3 LTS+)
- Unity C# Job System (
com.unity.jobs) - Unity Burst Compiler (
com.unity.burst) - Unity Mathematics (
com.unity.mathematics) - New Unity Input System (
com.unity.inputsystem) - DoTween / PrimeTween (For lightweight vector-based visual animations)
Assets/Scripts/
βββ FlyingAI/
β βββ Core/ # Base interfaces, FSM abstract base, & main agent (FlyingEnemy)
β βββ Behaviors/ # Flocking behavior logic & leader-follower steering
β βββ Formations/ # Formation definitions (V, Circle, Grid, Line) & Factory
β βββ Flocking/ # Parallel Jobs (FlockingJob, AvoidanceJob, Spatial Hashing Grid)
β βββ States/ # Concrete FSM States (Idle, Chase, Attack, Evade, etc.)
β βββ Combat/ # Weapon handling, projectile controls & IDamageable definitions
β βββ Managers/ # Global Swarm Controllers, Priority trackers, Wave Spawners
β βββ Pooling/ # Zero-allocation Object Pool classes
β βββ Events/ # Event argument and publisher definitions (Observer Pattern)
β βββ Rendering/ # FlyingEnemyLOD optimization system
β βββ Debug/ # Debug visualizers & editor helpers
β βββ UI/ # Canvas indicators & HUD controls
β βββ Utils/ # Custom Odin fallbacks
βββ ScriptableObjects/
β βββ Configs/ # ScriptableObject configurations for Waves, Weapons, and Formations
βββ Utils/
βββ DebugLogger.cs # High-performance, stripped conditional logger
- Strategy Pattern: Flocking behaviors, steering forces, and formations are encapsulated as strategy algorithms, swapped dynamically at runtime.
- Observer Pattern: A centralized type-safe event hub (
FlyingAIEvents) processes spawning, damage, death, and wave completion. - State Pattern: The modular AI transitions autonomously through state classes without complex nested
if-elseorswitchbranches. - Factory Pattern: Formations are generated polymorphically using
FormationFactorybased on configuration payloads. - Object Pool Pattern: Reuses enemy and projectile game objects from memory buffers, preventing performance hitches from garbage collection.
Below is a simplified example showing how flocking vectors are computed concurrently across worker threads using Unity Mathematics:
[BurstCompile]
public struct FlockingJob : IJobParallelFor
{
[ReadOnly] public NativeArray<FlockingData> AgentData;
[ReadOnly] public NativeParallelHashMap<int, int2> SpatialHash;
[ReadOnly] public NativeArray<int> SortedIndices;
public float CohesionWeight;
public float SeparationWeight;
public float NeighborDistance;
public float CellSize;
public void Execute(int index)
{
FlockingData currentAgent = AgentData[index];
float3 alignment = float3.zero;
float3 cohesion = float3.zero;
float3 separation = float3.zero;
int neighborCount = 0;
// Perform fast O(1) neighbor lookups using spatial hashing cell boundaries
int3 cellPos = GetCellPosition(currentAgent.Position, CellSize);
for (int x = -1; x <= 1; x++)
{
for (int y = -1; y <= 1; y++)
{
for (int z = -1; z <= 1; z++)
{
int hash = CalculateHash(cellPos + new int3(x, y, z));
if (SpatialHash.TryGetValue(hash, out int2 range))
{
for (int j = range.x; j < range.y; j++)
{
int neighborIndex = SortedIndices[j];
if (neighborIndex == index) continue;
float3 toNeighbor = AgentData[neighborIndex].Position - currentAgent.Position;
float sqrDist = math.lengthsq(toNeighbor);
if (sqrDist < NeighborDistance * NeighborDistance)
{
float dist = math.sqrt(sqrDist);
cohesion += AgentData[neighborIndex].Position;
alignment += AgentData[neighborIndex].Velocity;
separation += -toNeighbor / (dist + 0.001f);
neighborCount++;
}
}
}
}
}
}
// Apply weights and compile final steer force output...
}
}Uses [Conditional] attributes to eliminate overhead in release builds entirely:
/// <summary>
/// Static debug logger utility class.
/// Provides categorized logging with compile-time stripping for release builds.
/// </summary>
public static class DebugLogger
{
[Conditional("UNITY_EDITOR"), Conditional("DEVELOPMENT_BUILD")]
public static void Log(string message, LogCategory category, Object context = null)
{
LogInternal(LogLevel.Info, message, category, context);
}
[Conditional("UNITY_EDITOR"), Conditional("DEVELOPMENT_BUILD")]
public static void LogError(string message, LogCategory category, Object context = null)
{
LogInternal(LogLevel.Error, message, category, context);
}
}To test and set up the system inside your scene, follow these simple steps (see SETUP_GUIDE_PL.md for a detailed step-by-step setup guide in Polish):
- Install Dependencies: Make sure your project has the Burst, Mathematics, and Input System packages installed via the Unity Package Manager.
- Create Resources Configuration: Create a
DebugLoggerSettingsScriptableObject inside a folder namedResources(Assets/Resources/DebugLoggerSettings.asset) using the asset creation menu. - Prepare Prefabs: Attach the
FlyingEnemycomponent to an empty GameObject with aRigidbody(IsKinematic = true) and aSphereCollider(IsTrigger = true), then save it as a Prefab. - Set Up Orchestrator: Create a
GameManagerempty GameObject and attachSwarmController,FormationManager,SpawnManager, andEnemyPool. Assign your enemy prefab to the pool. - Enter Play Mode: Hit play and use the
DemoSpawnerkeyboard inputs:S- Spawns a single enemy.F- Spawns a complete squadron in formation.K- Instantly kills all spawned units to test recycling and pool optimization.
- Test Environment: Ryzen 5 5600X, RTX 3060, Unity 2022.3.10f1 (Standalone Build).
- Result: Stable 90+ FPS at 1080p resolution with 1,000 simultaneous agents simulating spatial hashed flocking, dynamic avoidance, and active combat state evaluations.
This project is licensed under the MIT License - see the LICENSE file for details.