Input Integration¶
Massive Swarm System ships an optional input layer that feeds movement directions into the swarm simulation from any player-controlled character. This page covers the IMoveInputSource contract, the Unity Input System adapter, and the mobile joystick canvas.
Optional package required
The Input System adapter components — InputSystemMoveInputSource and MobileTouchJoystickCanvas — live in the MassiveSwarmSystem.InputSystem assembly. That assembly only compiles when com.unity.inputsystem is installed in your project. The core runtime (MassiveSwarmSystem.Runtime) has no dependency on Input System and compiles cleanly without it.
If com.unity.inputsystem is not in your project, install it via Window → Package Manager → Unity Registry → Input System before using these components.
Overview¶
Any component that implements IMoveInputSource can feed movement to the swarm's player controller or any system that reads directional input.
Two ready-made implementations ship:
InputSystemMoveInputSource— wraps a UnityInputActionReference(e.g. aGameplay/Moveaction from your Input Actions asset).MobileTouchJoystickCanvas— builds a complete on-screen joystick at runtime, no prefab required. Simulates a virtual gamepad left-stick that anyMoveaction bound to<Gamepad>/leftStickpicks up automatically.
The IMoveInputSource Contract¶
IMoveInputSource is the only thing any system in this package needs to know about player input.
ReadMove() returns the current movement vector. The XY axes map to horizontal and vertical movement in whatever coordinate space the consuming system expects (typically world-relative XZ). Return Vector2.zero when there is no input.
Implement this interface on any MonoBehaviour to provide input from a source not covered by the shipped adapters — keyboard polling, a custom gamepad mapper, a nav-mesh-driven AI controller, or a replay system.
using MassiveSwarmSystem.Runtime.Input;
using UnityEngine;
public sealed class KeyboardMoveInputSource : MonoBehaviour, IMoveInputSource
{
public Vector2 ReadMove()
{
return new Vector2(Input.GetAxis("Horizontal"), Input.GetAxis("Vertical"));
}
}
Assign the component to whichever field on your player controller accepts an IMoveInputSource, and the swarm will call ReadMove() each fixed frame.
InputSystemMoveInputSource¶
Add via Component → Massive Swarm System → Input → Input System Move Input Source.
Reads a Vector2 action from the Unity Input System and exposes it through IMoveInputSource.
Requires com.unity.inputsystem
This component only compiles when the Input System package is installed. See the warning at the top of this page.
Inspector field¶
| Field | What it controls |
|---|---|
| Move Action | An InputActionReference pointing to a Vector2 Move action. Assign the Gameplay/Move action (or equivalent) from your Input Actions asset. |
How it works¶
On OnEnable, the component enables the assigned action if it is not already enabled, and disables it again on OnDisable — but only if this component was the one that enabled it. If the action was already running (managed by a PlayerInput component or an InputActionAsset enabled elsewhere), the component leaves it alone and does not disable it on teardown.
If no InputActionReference is assigned, ReadMove() returns Vector2.zero and a one-time warning is logged to the console.
Setup steps¶
- Create or open your Input Actions asset (Assets → Create → Input Actions).
- Add a Vector2 action named
Moveunder an action map (e.g.Gameplay). Bind it to the controls you need (keyboard WASD, gamepad left stick, etc.). - Add
InputSystemMoveInputSourceto the same GameObject as your player controller. - Drag the
Moveaction from the Input Actions asset into the Move Action field. - Assign the
InputSystemMoveInputSourcecomponent reference to your player controller's input source field.
MobileTouchJoystickCanvas — Mobile On-Screen Joystick¶
Add via Component → Massive Swarm System → Input → Mobile Touch Joystick Canvas.
Drop this component on any GameObject in your scene. When Play mode starts, it builds a self-contained Canvas with a draggable joystick. No prefab, no manual UI hierarchy needed — everything is created at runtime.
The joystick simulates a virtual gamepad left-stick by default (<Gamepad>/leftStick). Any Move action bound to that path receives the input without extra wiring.
Requires com.unity.inputsystem
This component only compiles when the Input System package is installed.
Quickstart¶
- Add an empty GameObject to your scene. Name it
Mobile Joystick. - Add Mobile Touch Joystick Canvas via the Component menu.
- Leave the defaults. Press Play. A joystick appears in the bottom-left corner (Editor counts as a touch platform under the default Activation Mode).
- If your
Moveaction already binds<Gamepad>/leftStick, input flows automatically. If not, add that binding or change Control Path to match your action.
Parameter Reference¶
Activation group¶
| Field | What it controls |
|---|---|
| Activation Mode | Auto Touch And Editor — shows the joystick in iOS/Android builds and in the Editor (default). Always — shows it on every platform. Touch Only — shows it only on touch-capable platforms at runtime, never in the Editor. |
| Mode | Fixed — joystick sits in a screen corner permanently. Follow Finger — joystick is hidden until touched; it appears under the finger and follows it past the outer ring. |
Fixed Layout group¶
Applies only when Mode is Fixed.
| Field | What it controls |
|---|---|
| Anchor | Which screen corner the joystick base sits in: Bottom Left, Bottom Right, or Bottom Center. |
| Anchor Offset | Pixel offset from the chosen corner to the joystick center, at the configured reference resolution. |
Follow Finger Layout group¶
Applies only when Mode is Follow Finger.
| Field | What it controls |
|---|---|
| Press Zone | Which portion of the screen reacts to touches: Full Screen, Left Half, or Right Half. |
| Inner Dead Zone | Dead zone as a fraction of the outer radius. Movements smaller than this give zero output. |
| Outer Saturation Padding | Once the finger is within this fraction of the rim, output locks to full magnitude. Improves the "full-speed" feel near the edge. |
| Base Follows Finger | When on, the base drags with the finger once the finger crosses the outer ring. When off, the knob saturates at the rim. |
| Show Follow Finger Visuals | When on, the base and knob are visible while the finger is pressed. Turn off for an invisible stick. |
| Fade Duration | Seconds for the base and knob to fade in on press and fade out on release. 0 is instant. |
| Secondary Tap Control Path | Input System control path for a secondary button. A second finger landing while the joystick is held sends a press to this control — useful for a jump button on the same touch zone. Default <Gamepad>/buttonSouth. Leave empty to disable. |
Visuals group¶
| Field | What it controls |
|---|---|
| Base Diameter | Diameter of the joystick base in pixels at the reference resolution. |
| Handle Diameter | Diameter of the draggable knob in pixels. |
| Movement Range | How far the knob travels from center (in pixels at the reference resolution) before the output magnitude saturates at 1. |
| Opacity | Overall opacity of the base and knob. |
| Base Color | Fill color of the outer base ring. |
| Handle Color | Fill color of the inner knob. |
Input System group¶
| Field | What it controls |
|---|---|
| Control Path | Input System control path the joystick simulates. Default <Gamepad>/leftStick. |
| Use Isolated Input Actions | Fixed mode only. Prevents the stick snapping back when control schemes auto-switch. Leave on unless your input setup has a specific reason to disable it. |
| Stick Behaviour | Fixed mode only. Passed to Unity's OnScreenStick.Behaviour. |
Canvas group¶
| Field | What it controls |
|---|---|
| Canvas Sort Order | Sort order of the runtime canvas. Raise this if your own UI renders on top of the joystick. |
| Reference Resolution | Reference resolution for the CanvasScaler (Scale With Screen Size mode). Match this to your game's design resolution. |
How the canvas is built¶
MobileTouchJoystickCanvas creates the entire UI hierarchy in code when the component first enables. It adds a Screen Space Overlay Canvas with a CanvasScaler and GraphicRaycaster, plus the joystick base, hit area, and knob Image components sized from your visual settings. If no EventSystem exists in the scene, it creates one with an InputSystemUIInputModule. If one exists without an InputSystemUIInputModule, the component replaces the existing input module so drag events reach the stick correctly.
The Canvas and its children are parented under the same GameObject as MobileTouchJoystickCanvas. Disabling the component hides the canvas; enabling it shows it again (or builds it for the first time).
Follow Finger mode for mobile games
For most mobile games, Follow Finger mode with Press Zone = Left Half is the best starting point. The joystick only occupies screen space while the player is touching it, and the base always appears where the finger lands — no learning curve.
FloatingOnScreenStick — Advanced Use¶
FloatingOnScreenStick is the lower-level component that MobileTouchJoystickCanvas uses internally in Follow Finger mode. You can add it directly to a UI Image when you want to build your own joystick visual hierarchy but still need the floating stick behavior.
Add via Component → Massive Swarm System → Input → Floating On Screen Stick. The component requires a RectTransform.
Inspector fields¶
| Field | What it controls |
|---|---|
| Control Path | Input System control path the stick drives. Default <Gamepad>/leftStick. |
| Base Rect | Optional RectTransform for the visible joystick base. Repositioned to the touch point on press; hidden when not pressed. |
| Knob Rect | Optional RectTransform for the draggable knob. Follows the finger within the outer radius. |
| Outer Radius | Distance from the base center in canvas units at which output magnitude reaches 1. |
| Follow Finger | When on, the base repositions when the finger passes the outer radius so the knob stays within range. |
| Inner Dead Zone | Dead zone as a fraction of Outer Radius. |
| Outer Saturation Padding | Saturation zone as a fraction of Outer Radius. Output locks to 1 before the finger fully reaches the rim. |
| Fade Duration | Seconds for base and knob to fade on press and release. 0 is instant. |
| Secondary Tap Control Path | A second finger landing while the joystick is held sends a press to this control. Default <Gamepad>/buttonSouth. Leave empty to disable. |
When to use FloatingOnScreenStick directly¶
Use FloatingOnScreenStick when you have your own joystick visual hierarchy and just need the floating-stick input behavior, or when the joystick must sit inside an existing Canvas you control.
Use MobileTouchJoystickCanvas when you want everything built automatically with no manual UI setup.
Attach to a raycast-target Image
FloatingOnScreenStick receives input through Unity's UI event system. Attach it to a RectTransform that has an Image with Raycast Target enabled — the stick will not receive pointer events without one. MobileTouchJoystickCanvas handles this automatically; it is only a concern when placing FloatingOnScreenStick manually.
Quickstart — wire input in this order
- Install
com.unity.inputsystemif you haven't already (Window → Package Manager → Unity Registry → Input System). - For keyboard/gamepad input: add
InputSystemMoveInputSourceto your player GameObject, assign yourMoveaction reference. - For mobile touch input: add an empty GameObject to the scene, add
MobileTouchJoystickCanvas, leave Mode = Fixed and press Play to confirm the joystick appears. - Switch to Mode = Follow Finger and Press Zone = Left Half once the basic flow works.
- Assign either component to your player controller's input source field.
- For a custom input source, implement
IMoveInputSourcedirectly on a MonoBehaviour and assign that instead.