Skip to content

FAQ

Common questions about buying, integrating, and customizing Massive Swarm System.

Can't find it here?

The Troubleshooting page covers first-run symptoms and their fixes. This page focuses on questions, not symptoms.


Before you buy

Does it require DOTS, ECS, or Burst?

No. The simulation is plain C# running in a single SwarmManager component. There are no references to com.unity.burst, com.unity.collections, or any ECS package in the runtime assembly, so it drops into a standard Unity project without any additional packages.

One nuance, since "plain C#" can read as "nothing is ever threaded": the optional Batched and Batched Deferred grounding modes gather ground casts into a SpherecastCommand buffer and let Unity run them on worker threads. That uses NativeArray and JobHandle from UnityEngine's own core modules, not the Jobs or Collections packages, so it adds no dependency. Grounding ships on Immediate, so nothing is threaded until you opt in.

Does it use Unity's NavMesh? Do I have to bake one?

No NavMesh and no NavMeshAgent. Agents route using behavior steering, obstacle physics queries, and optionally the built-in Surface Flow Field. The Surface Flow Field is off by default. When you enable it, it bakes its own grid at Play time (or via Bake Now on SwarmManager). No NavMesh bake needed.

See Navigation for when to enable it and how to set it up.

Which render pipelines does it support?

URP. The simulation core is render-pipeline-agnostic, but every visual that ships in the package is not: the VAT shaders (VatStandard, VatMobile, VatHigh) declare "RenderPipeline"="UniversalPipeline" in their SubShaders, and the sample and default agent materials are URP materials.

Open the package under the Built-in Render Pipeline or HDRP and agents render magenta. The editor warns you about this on import. Switching to the Animator plus SwarmAgentAnimation path does not fix it, because that path only drives an Animator and changes nothing about materials. What does fix it is supplying your own materials for the pipeline you are on. The simulation itself runs correctly either way, and agents move as they should behind the magenta.

Which Unity versions are supported?

Unity 2022.3 LTS and Unity 6 LTS.

How many agents can I realistically run?

The short answer: the bottleneck is almost always rendering, not the simulation.

Swapping a SkinnedMeshRenderer agent for a simple capsule is the quick way to see how much of your frame the prefab takes. Your actual ceiling depends heavily on your agent prefab.

See Performance for how to measure your specific case, and the Troubleshooting mobile section for the fix-priority list.

Why is my frame rate lower in the Editor than in a build?

Play Mode runs inside the Editor process and renders the Game View through an extra layer, so it is always slower than the same scene in a build. Open windows add to that. Unity's own Statistics window is the usual culprit, and an attached Profiler or a visible Scene View costs more again.

The measured benchmark on the Performance page was taken in a Windows release build, not in Play Mode, which is why it will not line up with the number your Editor shows. Build before you judge a frame rate, whether you are sizing your agent budget or checking that a tuning change actually helped.

See Performance: How to measure.

Does it run on mobile?

Yes, with the right prefab setup. Use a VAT agent (the Mobile or Standard shader tier), a single material per mesh, a low-poly mesh, and shadow casting off. The simulation itself is not the bottleneck on mobile. The agent prefab is.

See Performance: Mobile for the ordered fix list and Animation for the VAT bake workflow.

Can I use my own character models?

Yes. Any prefab works as an agent: assign it to a SwarmAgentArchetype and the swarm uses it. For high counts, the VAT Baker (Tools → Massive Swarm System → VAT Baker) converts a skinned character into a VAT prefab so the crowd renders without skeleton overhead.

See Animation: VAT bake workflow for the step-by-step.

Does it include health, damage, or combat logic?

The core simulation has no health system. What it does provide:

  • Per-agent attack state (tracking which agents are in range and firing).
  • An IDamageable interface in the runtime assembly that the swarm calls when a melee hit lands.

Implement IDamageable on anything you want the swarm to be able to hurt. It has three members: a CanTakeDamage gate and two ApplyDamage overloads, one plain and one carrying hit metadata. The swarm always calls the metadata overload, so implement it even if you ignore the context and forward to the plain one. Subclassing the ready-made sample components gets you there without thinking about it.

The swarm does not manage your player's HP or death. That stays in your own code.

See Combat Integration for the full contract reference.

Does it require the new Input System package?

The core runtime does not. There is a separate optional assembly, MassiveSwarmSystem.InputSystem, that wraps the new Input System for the player-movement helpers in the sample scenes. It compiles only when com.unity.inputsystem is present and declares a versionDefines constraint on that package, so it has no effect on a project that doesn't have it.

Can the swarm chase multiple targets?

Yes. SwarmTarget components register automatically with SwarmManager on enable, and registration is unbounded, so you can have as many targets as you like in the scene. Each simulation tick, the manager fills Max Active Target Count slots (default 10, configurable on SwarmManager) with the registered targets closest to the centre of the swarm, and a target the swarm is already fighting keeps its slot. Each agent then chases the nearest target in that set. Agents use per-agent hysteresis when switching between targets to avoid constant thrashing.

Is full C# source included?

Yes. There are no precompiled DLLs in the package. Everything ships as C# source.


There are a lot of settings. Do I have to learn them all?

No. The three inspectors with the most fields, SwarmManager, SwarmSettings and the SwarmBehaviorProfile, open in Simple mode, which shows the settings most projects touch first and hides the rest. The Getting Started walkthrough reaches a working swarm without changing any of them, since the shipped profiles are tuned to run as they are.

Hidden is not off. A setting Simple does not draw keeps running with the value it has. Switching to Advanced is for particular jobs: four extra steering behaviors, the Surface Flow Field tuning fields, and the deeper grounding, timestep and dormancy controls. When you need one and do not know where it sits, Swarm Settings and the Behavior Profile have a search box that reads field names, tooltips and symptom words such as "jitter", across both modes at once. Each field also carries a colored dot rating what it costs as the swarm grows. See Finding a Setting.


Integration and customization

Can I add my own steering behaviors?

Not by subclassing a base class or dropping in a component. The steering pipeline is a set of static methods in SwarmBehaviorRuntime that SwarmManager calls in a fixed sequence. Adding a new behavior today means editing that class (it is internal to the runtime assembly) and wiring the call into the step loop. The SwarmBehaviorProfile ScriptableObject controls which built-in behaviors are active and their weights.

If custom behaviors are important for your project, budget time for that code change before buying.

How do I read or drive agent data at runtime?

SwarmManager exposes stable handles for spawning and despawning:

  • TrySpawnAgent(...): several overloads. Each returns bool, false when the swarm is at capacity, and hands back the handle through an out SwarmAgentHandle parameter. Three of the overloads skip the handle entirely for fire-and-forget spawns.
  • DespawnAgent(handle): removes an agent immediately.
  • TryGetAgentPosition(handle, out Vector3): reads the simulation position by handle.

For bulk reads, use ReadAgentPositions, which reads without copying the internal arrays. There is no way to reach SwarmAgentData from your own code and that is deliberate: the class and the manager's property that exposes it are both internal, and internals are shared only with the package's own editor assembly. Even the shipped samples go through the public handle-keyed getters and bulk readers, which is how those stay honest.

See the SwarmManager reference for the full API list.

Why doesn't it use Jobs or Burst: wouldn't that be faster?

The simulation was measured. Threading the core sim loop through Burst saved too little at typical agent counts to justify the effort involved and the compatibility risk across Unity versions. The real cost at high counts is the visual sync: moving hundreds of GameObjects each frame. That is where future optimization work is targeted.

The one place work already runs off the main thread is optional grounding: see the batching note under Does it require DOTS, ECS, or Burst? above.

Is the simulation deterministic?

No guarantee. The simulation runs on a fixed timestep in FixedUpdate, which is repeatable frame to frame, but body blocking physics queries depend on Unity's physics engine and spatial hash order, both of which can vary with collider ordering and frame timing. Do not rely on replay-exact determinism.

Can obstacles move at runtime?

A moving collider on a layer in Obstacle Layer Mask keeps agents out, with brief overlap at its leading edge. The baked Surface Flow Field does not know about it, so routes do not bend around it, and it does not re-scan colliders on its own after the bake. RebuildSurfaceFlowNavigationNow() rebuilds the whole map in one blocking call, which suits a level that changes once and not an obstacle that moves every frame. In a Surface Flow scene, put a Swarm Flow Modifier on anything that moves or opens, which restamps its cells with no rebake.

See Physics & Colliders: Moving obstacles for the setup.

My Rigidbody passes through the agents. Why?

Agents are not driven by Unity's physics, and their colliders are static colliders. Whether a Rigidbody passes through them depends on the layer collision matrix: with the pair off it slides through, with the pair on and solid agent colliders it stops like against a wall and the agents are unaffected. For a prop the crowd should give way to and push back on, add a Swarm Flow Modifier and a Swarm Pushable.

See Physics & Colliders: Rigidbody props for the table and the steps.

Does it work for multiplayer?

There is no built-in networking. The simulation is fully local and manager-driven: positions live in flat arrays on SwarmManager, not in networked objects. You can synchronize swarm state over the network by driving SwarmManager on the authoritative peer and broadcasting positions, but the system does not provide that infrastructure. It is not designed as a networked simulation out of the box.

Can I make flying or non-grounded agents?

Yes. Grounding is a setting, not a requirement. Turn off Enable Grounding on SwarmSettings (and, if you use the Surface Flow Field, set Surface Flow Grounding Mode to Disabled too, since it grounds agents on its own), and agents move at whatever Y position they were spawned at, driven by steering alone. There is no gravity, so they stay at that height unless you push them externally. For agents that should track terrain height while airborne, leave grounding on and tune Ground Layer Mask to the surface you want them to follow; a visual offset in the prefab makes them float above it. See Physics & Colliders: Ground, slopes and steps.

My player climbs on top of the agents. How do I stop it?

Exclude the agent layer on the player's Character Controller, then push the player out of agent bodies yourself, horizontally only. Step Offset is not the cause, so lowering it does not help. The shipped DemoPlayerController contains the separation code.

See Physics & Colliders: The player for the cause, both ways to stop the engine resolving the overlap, and the fields that make the sample work.


Still have questions?