UGTK cat mascotUGTKengine within an engine Request access

UGTK / Toolkit / Utility Systems / Vibration System (Utility) Completed

Utility Systems — UGTK

Vibration System

Summary

VibrationSystem is a utility module for mobile haptics and WebGL vibration integration.
It exposes a global singleton manager (Mn_VibrationManager) and a spatial 3D emitter (Mn_SpatialVibrationEmitter) that applies distance, directional, and occlusion logic inspired by the directional approach used in the audio spatial module.


Content


Modules Dependencies

The module depends on:


Setup

  1. Add Mn_VibrationManager to a GameObject in scene.
  2. Optionally assign an explicitListener transform for 3D spatial evaluation.
  3. Add Mn_SpatialVibrationEmitter to world objects that should emit directional vibration.

How To Use

Example API calls:

Mn_VibrationManager.Instance.VibrateLight();
Mn_VibrationManager.Instance.VibrateMedium();
Mn_VibrationManager.Instance.VibrateHeavy();
Mn_VibrationManager.Instance.VibrateMilliseconds(80);
Mn_VibrationManager.Instance.VibratePattern(new[] { 30, 50, 90, 60, 120 }, -1);

Spatial call:

Mn_VibrationManager.Instance.TryVibrateSpatialAt(
    worldPosition: transform.position,
    forwardDirection: transform.forward,
    baseDurationMs: 90);

3D Spatial Behaviour

The intensity is computed from:

This makes vibration strength context-aware in 3D scenes and coherent with directional gameplay feedback.


Editor Testing

Custom inspectors are included:

Note: vibration is ignored in Edit Mode when not running Play Mode.


Testing Scene

Open Debug/VibrationScene.unity. It holds VibrationManager with Mn_VibrationManager, and spatialemitter with Mn_SpatialVibrationEmitter. The manager's inspector ends in a Testing block whose buttons fire the real calls.

What you actually feel depends on where you are, and the help box under the buttons says so:

The 3D Spatial Evaluation block above drives Mn_SpatialVibrationEmitter: intensity falls off between Min Distance and Max Distance from the listener, and Occlusion Mask lets a wall between emitter and listener damp it. Turn on Draw Spatial Debug to see the two radii in the Scene view while placing an emitter.


Technical Info

Path Content
Scripts/Runtime/Manager/Mn_VibrationManager.cs The singleton: VibrateLight/Medium/Heavy, VibrateMilliseconds, VibratePattern, the on/off switch, and the spatial helpers EvaluateSpatialIntensity and TryVibrateSpatialAt
Scripts/Runtime/3D/Mn_SpatialVibrationEmitter.cs Emitter placed in the world: the closer and the more in front of the listener it is, the stronger the pulse
Scripts/Editor/Mn_VibrationManager_Editor.cs Inspector with the test buttons for each strength and for a custom pattern
Scripts/Editor/Mn_SpatialVibrationEmitterEditor.cs Inspector for the emitter, with the gizmo range and a live intensity readout

Haptics do not exist on a desktop, but a gamepad does. The module has two independent outputs and they behave very differently:

Output In the editor On a device
Device haptics (VibrateLight/Medium/Heavy, VibrateMilliseconds, VibratePattern) silent no-op Android gives real millisecond patterns; iOS maps the strengths onto its own system feedback and ignores custom patterns entirely
Gamepad rumble (StartNonDirectionalRumble, the directional helpers) works, even outside Play, which is what the inspector's test buttons use works wherever the Input System sees a gamepad

So a scene that "looks like it works" at a desk proves something about the rumble and nothing at all about the phone.

The rumble path is compiled behind UNITY_INPUT_SYSTEM, which the module's assembly definition now raises through a versionDefines entry on com.unity.inputsystem. Before that entry existed the symbol was defined nowhere, so every rumble block was stripped: the four Gamepad Rumble settings appeared in the inspector and controlled nothing. If rumble is silent in your project, check that the Input System package is installed — that is the switch.


© 2026 Marcello De Bonis. All rights reserved.

Real dependenciesOpen in the map →

Depends on 1

Used by 0

  • No other module depends on it.

Measured from the repository: code references (asmdef) plus prefab and asset GUIDs. Importing this module alone brings in 1 module in total.