Over the last eight years, I have hit the classic C# object overhead wall more times than I care to admit. When you are trying to manage hundreds—or thousands—of active AI agents, UI elements, or environmental states using standard MonoBehaviour scripts, Garbage Collection (GC) spikes and CPU cache misses quickly ruin your frame budget. Traditional visual scripting tools build deep C# class hierarchies that look neat on paper but grind runtime performance to a halt at scale.
This is precisely where State Designer - DOTS Powered Finite State Machines steps in. Instead of executing visual nodes through standard reference-heavy C# objects, this asset generates low-level, high-performance data structures built on Unity's Data-Oriented Technology Stack (DOTS). It bridges the gap between readable, graph-based Finite State Machine (FSM) architecture and cache-friendly execution powered by Unity Entities, the C# Job System, and the Burst Compiler.
Here is the key takeaway: high-level state logic is designed visually inside a modern GraphView interface, but at runtime, the graph is evaluated directly as pure struct data stored in contiguous memory chunks. You get the maintenance advantages of visual FSMs alongside the pure processing horsepower of data-oriented design.
The asset isn't just a basic visual wrapper; it is tailored specifically to fit into production-grade ECS pipelines. Here is a breakdown of what stands out under the hood:
IComponentData structs, ensuring optimal L1/L2 CPU cache utilization during state evaluations.Entities Package visualizers.MonoBehaviour game logic and high-performance DOTS entities.In traditional FSMs, switching states requires calling virtual methods like OnStateExit() and OnStateEnter(), which trigger vtable lookups and delegate allocations. In State Designer, transition evaluation occurs inside parallel jobs. State IDs are mutated as raw int or enum values inside a struct, completely skipping memory allocation during state transitions.
By moving state logic into contiguous arrays managed by Native Containers, the tool keeps runtime memory allocation strictly at zero during normal gameplay loops. This eliminates the dreaded mid-game frame stutter caused by garbage collector collection sweeps.
While traditional visual script tools work fine for small single-player games, this DOTS-powered solution shines in complex, high-entity scenarios:
Setting up State Designer in a modern Unity project (using Unity 2022.3 LTS or Unity 6) requires setting up your backing data structs and linking the baked authoring graph. Below is a practical step-by-step example for creating a performant enemy state handler.
First, create a clean component struct that holds your state machine variables using pure DOTS primitives:
using Unity.Entities;
using Unity.Mathematics;
public enum EnemyState
{
Patrol = 0,
Chase = 1,
Attack = 2
}
public struct EnemyStateComponent : IComponentData
{
public EnemyState CurrentState;
public float StateTimer;
public float DetectionRadius;
public float3 TargetPosition;
}
Attach an authoring component to your GameObject prefab to convert your high-level visual graph into runtime entity data when baked:
using Unity.Entities;
using UnityEngine;
public class EnemyStateAuthoring : MonoBehaviour
{
public float InitialDetectionRadius = 10.0f;
public EnemyState StartingState = EnemyState.Patrol;
public class EnemyStateBaker : Baker<EnemyStateAuthoring>
{
public override void Bake(EnemyStateAuthoring authoring)
{
Entity entity = GetEntity(TransformUsageFlags.Dynamic);
AddComponent(entity, new EnemyStateComponent
{
CurrentState = authoring.StartingState,
StateTimer = 0.0f,
DetectionRadius = authoring.InitialDetectionRadius,
TargetPosition = Unity.Mathematics.float3.zero
});
}
}
}
To evaluate states concurrently across thousands of entities, run an ISystem utilizing the Burst Compiler:
using Unity.Burst;
using Unity.Entities;
using Unity.Transforms;
[BurstCompile]
public partial struct EnemyStateSystem : ISystem
{
[BurstCompile]
public void OnUpdate(ref SystemState state)
{
float deltaTime = state.WorldUnmanaged.Time.DeltaTime;
new ProcessEnemyStatesJob
{
DeltaTime = deltaTime
}.ScheduleParallel();
}
}
[BurstCompile]
public partial struct ProcessEnemyStatesJob : IJobEntity
{
public float DeltaTime;
void Execute(ref EnemyStateComponent enemyState, ref LocalTransform transform)
{
enemyState.StateTimer += DeltaTime;
switch (enemyState.CurrentState)
{
case EnemyState.Patrol:
// Patrol transition logic executed in parallel job
if (enemyState.StateTimer > 5.0f)
{
enemyState.CurrentState = EnemyState.Chase;
enemyState.StateTimer = 0.0f;
}
break;
case EnemyState.Chase:
// Chase logic handled without garbage allocation
break;
}
}
}
In my experience, no asset is a complete silver bullet. Here is an honest appraisal of where this asset excels and where you need to be careful.
Entities, Unity.Mathematics, and modern baking workflows.MonoBehaviour patterns must learn ECS concepts like baking, component structs, and parallel jobs.| Category | Tools / Visual Scripting |
|---|---|
| Latest Version | v1.3.3 (3 tracked releases) |
| File Size | 121.32 MB |
| Added to Platform | May 7, 2026 |
| Views | 11 views |
| Downloads | 3 downloads |
| Favourites | 1 favourites |
| Official Store | Buy Original License on Unity Asset Store → |
| Issue with Package? | Report Broken Link → |