Skip to content

SwarmTarget

namespace MassiveSwarmSystem.Runtime

A MonoBehaviour that marks a GameObject as something the swarm chases — the player, a decoy, an objective. Add it to any GameObject and the swarm picks it up automatically; no manager reference is required.

Setting it up in the Inspector

This page is the scripting view of SwarmTarget. If you just want to drop the component on a GameObject and tune it in the Inspector, see Targets instead.

How it registers

While the component is enabled it registers its Transform with the active SwarmManager; when disabled or destroyed it unregisters itself. You never wire up a reference by hand.

  • Registration happens on OnEnable. The component runs at DefaultExecutionOrder(-900), so it registers before the manager reads its targets each FixedUpdate.
  • If no manager exists yet when the target enables, registration is retried once in Start.
  • The manager can track several targets at once and switches between them with hysteresis. See Max Active Target Count.

The common runtime patterns need no manager calls at all:

using MassiveSwarmSystem.Runtime;
using UnityEngine;

public class DecoyController : MonoBehaviour
{
    // Spawn a temporary distraction the swarm will chase.
    public GameObject SpawnDecoy(GameObject prefab, Vector3 position)
    {
        GameObject decoy = Instantiate(prefab, position, Quaternion.identity);

        // Adding the component (on an active GameObject) fires OnEnable, which
        // registers the decoy with the active SwarmManager automatically.
        decoy.AddComponent<SwarmTarget>();
        return decoy;
    }

    // Disabling or destroying the target unregisters it; agents fall back to
    // whatever targets remain.
    public void ReleaseDecoy(GameObject decoy) => Destroy(decoy);
}

Body radius

SwarmTarget resolves a body radius — how wide the target's body is, in world units — that the swarm uses to surround and stop around it. The value is computed from colliders (or an explicit number) and then cached, so the per-frame target snapshot never walks colliders.

The auto-detect rules and the Inspector fields are described in full on the Targets page. From code, the resolved value is read-only:

SwarmTarget target = GetComponent<SwarmTarget>();

float radius = target.BodyRadius; // resolved radius, world units

if (target.RadiusSource == SwarmTarget.BodyRadiusSource.AutoDetect && !target.HasDetectedSource)
{
    // Auto Detect found no collider or CharacterController to measure,
    // so BodyRadius is the 0.5 fallback. Add a Capsule/Box sized to the body.
    Debug.LogWarning($"{name}: swarm target has no measurable collider.", this);
}

Recompute after changing colliders at runtime

BodyRadius is cached at OnEnable / OnValidate. If you resize, add, or remove a collider while the game is running, call RefreshBodyRadius() so the swarm sees the new size:

capsule.radius = 1.5f;     // grew the body at runtime
target.RefreshBodyRadius(); // re-measure and re-cache

Public API

All properties are read-only — configure the target through the Inspector (or OnValidate in the editor), not from code. The only mutating entry point is RefreshBodyRadius().

Member Type Description
RadiusSource BodyRadiusSource How BodyRadius is resolved — AutoDetect from colliders, or Manual from an explicit value.
IncludeChildColliders bool When auto-detecting, whether child colliders are also measured. A CharacterController is only ever read from this GameObject, never from children.
ManualBodyRadius float The explicit radius, in world units, used only when RadiusSource is Manual.
BodyRadius float The resolved radius, in world units, the swarm actually uses. Falls back to 0.5 when auto-detect finds nothing measurable.
HasDetectedSource bool true when auto-detect found a usable collider or CharacterController. false in Manual mode, or when nothing was found and BodyRadius is the 0.5 fallback.
RefreshBodyRadius() void Recomputes and caches BodyRadius from the current settings. Call after changing colliders at runtime.

BodyRadiusSource

public enum BodyRadiusSource
{
    AutoDetect = 0, // measure from colliders / CharacterController on this GameObject
    Manual     = 1, // ignore colliders and use ManualBodyRadius
}

Quick reference in your IDE

Key members carry a short XML summary, so hovering them in Visual Studio or Rider shows a one-line description while you code. This page has the full detail.