UGTK / Toolkit / Utility Systems / Vibration System (Utility) Completed
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:
UGTK.DesignPattern.Singleton(for global manager access)
Setup
- Add
Mn_VibrationManagerto a GameObject in scene. - Optionally assign an
explicitListenertransform for 3D spatial evaluation. - Add
Mn_SpatialVibrationEmitterto 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:
- Distance factor (
minDistance-> full,maxDistance-> zero) - Direction factor (listener facing and source facing)
- Occlusion factor (raycast attenuation)
This makes vibration strength context-aware in 3D scenes and coherent with directional gameplay feedback.
Editor Testing
Custom inspectors are included:
Mn_VibrationManager_Editorwith quick buttons (Light/Medium/Heavy/Pattern)Mn_SpatialVibrationEmitterEditorwith play-test buttons and intensity logger- Scene handle for
gizmoDistanceon spatial emitter
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.
- Test Light, Test Medium, Test Heavy — the three intensities, using the durations set just above them (25, 60 and 120 ms by default). Changing those fields changes what the buttons do, which is the quickest way to find a feel that suits the game.
- Test Pattern (Short) plays a short sequence rather than a single pulse.
- Stop Rumble (gamepad) cuts it off.
What you actually feel depends on where you are, and the help box under the buttons says so:
- Gamepad rumble works in the editor, outside Play Mode included. If nothing happens, move a stick on the pad first — a controller that has not reported anything recently is not considered connected.
- Phone and WebGL vibration only work in Play Mode, and only on the device itself. There is no desktop equivalent, so the buttons are the only way to check the timings before a build.
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.
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.
UGTKengine within an engine


