Animation¶
How Massive Swarm System animates agents, and how to pick the right approach for your target hardware.
Choosing an approach¶
| Approach | Best for | Cost |
|---|---|---|
| VAT (Vertex Animation Texture) | Mobile, 1000+ agents, GPU instancing | Very low |
Animator + SwarmAgentAnimation |
Richer character animation at lower counts | Medium–high (skinned mesh) |
| No animation component | Rigid-body enemies, simple shapes | Minimal |
VAT Animation¶
VAT bakes skeletal animation into a texture. At runtime the agent mesh samples the texture to reconstruct vertex positions — no skeleton, no SkinnedMeshRenderer, no per-bone CPU work.
VAT agents use SwarmVatAnimation (added to the prefab), which SwarmVisualManager drives each frame. Each agent keeps its own MeshRenderer, and because the generated VAT material has GPU instancing enabled, Unity batches the identical draws automatically. The VAT baker window is at Tools → Massive Swarm System → VAT Baker.
When to use VAT: targeting mobile, or when skinned mesh cost is visible in the profiler at your target agent count.
When not to use VAT: when you need real-time bone manipulation, IK, or procedural animation that cannot be pre-baked.
VAT bake workflow¶
- Assign a source skinned mesh prefab and animation clips in the VAT baker window.
- Click Bake VAT Prefab. The baker generates a
.asset(VAT data), a.mat(VAT material), and a ready-to-use prefab. - Assign the generated prefab to the agent archetype.
- At runtime,
SwarmVisualManagerupdates each agent'sSwarmVatAnimation, which writes that agent's clip and tint data into itsMeshRendererthrough aMaterialPropertyBlock. Because the VAT material has GPU instancing enabled, Unity batches the draws.
VAT Baker field reference¶
Open the baker at Tools → Massive Swarm System → VAT Baker. The window has a Simple / Advanced toggle and a Single Prefab / Batch toggle at the top.
Simple mode walks you through four numbered sections and hides advanced overrides. Advanced exposes clip loop flags, sample rate, and the normal-bake toggle. Use Simple for everyday bakes; switch to Advanced only when you need to override the preset's defaults.
Single Prefab bakes one source at a time. Batch bakes a list of prefabs that share the same clips, preset, and output folder — each prefab writes its own named VAT asset.
Section 1 — Source Prefabs¶
| Field | What it does |
|---|---|
| Model Or Prefab | The prefab, model asset, or scene object that contains the source skinned renderer. Drag directly into the drop zone or use the object field. |
| Source Renderer | The body anchor: the SkinnedMeshRenderer whose material becomes slot 0. Auto-set to the highest-vertex skinned mesh. Other skinned meshes on the character bake in alongside it — see Multi-part characters. |
| Avatar | Avatar used by the temporary sampling Animator. Required for humanoid clips when the source has no Animator with an Avatar of its own. |
Batch mode shows an additional Avatar field labeled Shared / Fallback Avatar. Prefabs in the batch that already carry their own Animator + Avatar use their own; the fallback only applies to prefabs without one (typically FBX models imported without a rig). Use Auto Fill to pick the first available avatar from the batch list.
Section 2 — Animation Clips¶
| Field | What it does |
|---|---|
| Idle | Looping idle animation. Required for the agent to stand still. |
| Walk | Looping locomotion clip at walk speed. |
| Run | Looping locomotion clip at run speed. |
| Attack (Optional) | Optional one-shot attack clip. When baked, SwarmVatAnimation.TryPlayAttack() plays it at runtime. Leave empty if the archetype has no attack animation. |
Use Auto Find Clips to scan the source asset, its Animator Controller, and the current selection for clips named like idle, walk, run, or attack.
In Advanced mode, a Loop toggle appears inline for each clip. Simple mode keeps all locomotion clips looping and the attack clip one-shot, matching the expected runtime behavior for most archetypes.
Attack clip loop flag
The attack clip defaults to non-looping (one-shot). Enable the loop toggle in Advanced mode only for channeled attacks — looping an attack clip with TryPlayAttack will cause the animation to repeat indefinitely until another clip interrupts it.
Advanced Bake Settings (Advanced mode only)¶
| Field | What it does |
|---|---|
| Sample Rate | Frames sampled per second for each clip. Range 1–60. Lower values reduce texture size; higher values preserve fast motion. For clips used as slower-playback fallbacks (walk/run), the baker automatically raises the effective sample rate proportionally to maintain visual quality. |
| Bake Normals | Bake animated normals into a second texture for lit shading. Doubles the texture memory cost. Disable this on mobile to reduce GPU bandwidth. |
In Simple mode these settings are driven by the selected Preset. Switch to Advanced only when you need to override them.
Section 3 — Output¶
| Field | What it does |
|---|---|
| Output Folder | Asset-relative folder where the .asset, .mat, and prefab are saved. Use Pick Folder to browse or Use Default to reset to the package default. |
| Create VAT Material | Create a material wired to the baked VAT asset using the package VAT shader. Disable only if you have a custom material pipeline. |
| Create Ready Prefab (Simple mode) | Also output a prefab pre-wired to the baked asset and material. Disable to get raw VAT assets for a custom pipeline. |
| Update Linked Material (rebake only) | Refresh the existing linked material in place so renderers keep their material reference rather than pointing at a new file. |
Section 4 — Ready to Bake (Simple mode)¶
This section shows an estimated texture memory cost based on the baked vertex count (the body plus every included part), sample rate, and total clip duration. A traffic-light indicator flags the budget tier: green for desktop-safe, amber for large-but-manageable, red for likely too heavy for mobile. Review the estimate before baking on mobile targets.
Click Bake VAT Prefab (or Bake VAT if prefab output is disabled) to run the bake. The baker writes the generated assets to the output folder and shows a report in the section below.
Bake presets¶
The Bake Preset dropdown (collapsed by default in Simple mode) selects from three built-in presets. Each preset sets the sample rate, normal-bake flag, and the tier render shader together. Choose the preset that matches your target platform, then override individual settings in Advanced mode only if the preset is not quite right.
| Preset | Description |
|---|---|
| Mobile | Cheapest tier for the big crowd. Skips the normal texture, so shading is flatter at distance — the right trade for 1000+ swarms and on-device builds. |
| Standard | Balanced default. Full surface detail (normal, metallic, occlusion) lit by the main light with soft shadows. Good for hundreds of agents on desktop. |
| High | Showcase tier. Adds dynamic point and spot lights plus reflection-probe blending on top of Standard — for hero shots and small counts. |
See VAT Render Quality Tiers for a full breakdown of what each tier costs and when to switch.
Quickstart — typical bake steps
- Select a preset that matches your target platform.
- Assign the source prefab (drag into the drop zone).
- Assign clips — use Auto Find Clips first.
- Confirm the memory estimate looks reasonable for your target.
- Click Bake VAT Prefab.
Multi-part characters¶
Most characters are more than one mesh. The body is often split across several SkinnedMeshRenderers — body, armor, skirt, shoulder pads — and weapons or cosmetics ride the bones as rigid MeshRenderers. The baker folds all of them into one VAT mesh, so the whole character animates from a single texture and renders in one draw, with no objects to sync at runtime.
Skinned parts. When the source has more than one SkinnedMeshRenderer, a Character Parts list appears under the Source section. The highest-vertex mesh is the body anchor (marked Body); every other skinned mesh is listed with an include toggle, on by default. Untick a part to leave it out, or press Use as body to make a different mesh the anchor. They share the source skeleton, so each part deforms with the animation exactly as it does in the original prefab.
Weapons and attachments. A rigid weapon, shield, or cosmetic that sits on (or under) one of the character's bones bakes the same way — it follows the bone for free. These appear in a separate Weapons & Attachments list. A mesh is eligible when it carries a MeshRenderer and MeshFilter and rides a bone of the body anchor. Both lists stay hidden when the character has none.
Materials and draw calls. The anchor's first material is slot 0. Every other distinct material across the baked parts gets its own slot, and parts sharing a material share a slot. The picker shows the cost live:
- A part that uses the same material as the body adds no draw calls.
- A part that needs its own material becomes one extra material slot: one extra draw call per agent. At a thousand agents that is a thousand extra draws, so share materials between parts where you can.
The rest is free. Every part shares the body's position and normal textures and the same per-agent material property block, so tint, damage flash, dissolve, and Importance-LOD changes reach them together with the body. Animated bounds grow to enclose them.
VAT Importance LOD¶
When Enable VAT Quality LOD is on in SwarmSettings, the simulation writes a per-instance quality tier into each agent's shader state. At Reduced and Cheap tier, frame interpolation is disabled on all three render shaders. Normal-texture behavior at distance depends on the tier: Standard and High keep the per-vertex baked normal on distant agents so they stay shaded; Mobile drops the normal tap at Reduced and Cheap tier to save GPU bandwidth (one position tap per vertex instead of two). At Cheap tier all shaders snap to the dominant walk/run clip. The per-pixel normal-map detail (surface Normal Map texture) is not distance-gated — it is always on or off based on the material keyword, regardless of LOD tier.
See VAT Render Quality Tiers for the full tier breakdown.
Animator-Based Animation (SwarmAgentAnimation)¶
For agents that need Animator blend trees, transition logic, or per-parameter animation control, add SwarmAgentAnimation to the prefab. It writes speed float parameters to the Animator based on the agent's simulated velocity.
SwarmAgentAnimation is visibility-aware: when the agent's renderer has been off screen past the grace period, it skips Animator.SetFloat calls entirely. This reduces the cost of Animator parameter updates for off-screen agents — no blend-tree evaluation is triggered for values that nobody will see.
Key fields:
| Field | What it does |
|---|---|
| Forward Speed Parameter Name | Animator float that receives forward/backward speed. Leave empty to disable. |
| Strafe Speed Parameter Name | Animator float that receives left/right speed. Leave empty to disable. |
| Use Planar Speed When Strafe Parameter Missing | When no strafe float is configured, writes total planar speed into Forward Speed so 1D blend trees still animate while agents sidestep. |
| Update Only When Visible | Skips parameter writes when the agent's renderer is off screen. |
| Visibility Grace Time | Keeps updating briefly after leaving the camera view to prevent pop at the screen edge. |
Culling mode: by default, SwarmAgentAnimation applies AnimatorCullingMode.CullCompletely to every spawned agent. This is the cheapest culling mode — the Animator stops evaluating entirely when off screen. Change Animator Culling Mode in the component if you need a different mode.
Importance LOD and animation refresh¶
When Importance LOD is active, SwarmVisualManager refreshes Animator and VAT playback parameters less often for Reduced and Cheap tier agents. The refresh interval is set by Reduced Animation Refresh and Cheap Animation Refresh in SwarmSettings. Higher values reduce the frequency of Animator.SetFloat calls (for SwarmAgentAnimation agents) and MaterialPropertyBlock writes (for non-instanced VAT agents) at the cost of slightly coarser animation cadence on distant agents.
SwarmVisualManager¶
SwarmVisualManager owns the agent visual layer. It maintains a pool of visual GameObjects per prefab and, for archetypes that opt into GPU instancing, issues Graphics.DrawMeshInstanced draw calls each frame. Every frame it reads simulation state from SwarmManager and updates transforms, Animator parameters, and VAT playback data — visuals follow the simulation, never the other way around.
SwarmManager creates and wires SwarmVisualManager automatically when you use the Create Swarm Manager menu item. You only need to add or configure it by hand when building a custom setup.
Inspector fields¶
| Field | What it controls |
|---|---|
| Swarm Manager | The SwarmManager that owns the simulation data. Auto-assigned when both components share a GameObject. |
| Fallback Agent Prefab | Prefab used when a spawn request or archetype supplies no prefab. Assign the built-in MSS Default Agent here for quick testing before your own art is ready. |
| Agent Root | Parent transform for pooled agent instances. Defaults to this GameObject when left empty. |
| Initial Pool Size | Per-prefab warm-up count. Pre-allocates this many instances when the first agent of that prefab spawns to reduce spawn spikes. This is not the simulation cap — total live agents are bounded by SwarmSettings → Max Agents, and pools grow past this value on demand. |
| Instanced Culling Camera | Camera used for per-instance CPU frustum culling before Graphics.DrawMeshInstanced submissions. Auto-resolves to the main camera when left empty. Instanced rendering does not cull instances automatically, so leaving culling on is almost always correct. |
| Disable Instanced Frustum Culling | Turns off per-instance frustum culling. Only useful when all active agents are guaranteed to always be on screen. Off by default — culling is on. |
| Instanced Shadow Casting Mode | Shadow casting mode for instanced draw calls. Defaults to Off because DrawMeshInstanced has no per-instance shadow culling — every active agent would cast a shadow even when off-screen. |
| Instanced Receive Shadows | Whether instanced agents receive shadows. |
| Instanced Layer | Unity layer used when issuing instanced draw calls. |
GPU Instanced Rendering¶
Enable Use Instanced Rendering on a SwarmAgentArchetype to render that archetype via Graphics.DrawMeshInstanced instead of one MeshRenderer per agent. This is considerably cheaper at high agent counts.
Requirements:
- The prefab must not use a
SkinnedMeshRenderer. If it does, instanced rendering is skipped automatically. - The material must support GPU instancing.
- Shadows require a shadow-casting pass in the shader; some instanced shaders omit it.
When to enable: any archetype with a non-skinned mesh and a high spawn count. Combine with VAT for the best throughput — baked VAT uses a static mesh that works with instanced rendering.
Mobile prefab checklist¶
Apply these before releasing on mobile
- Use VAT animation instead of
SkinnedMeshRenderer+Animator. - Enable Use Instanced Rendering on the archetype.
- Use a single material per agent (no multi-material mesh).
- Keep the mesh low-poly.
- Disable shadow casting on the agent renderer.
- Set Animator Culling Mode to
Cull Completelyif usingSwarmAgentAnimation.