Microtube Docs
Developers / Unity / Haptics setup

Unity haptics setup

How HEXR haptics work, how to add them with or without code, and how to design them so they feel right.

How haptics work

Every haptic takes the same path, whatever starts it:

Add haptics without code

Three components cover most objects. Add them in the Inspector like any other component.

Feel an object you grab — HexRInteractableHaptics

The place to start. It presses the fingers while your XR SDK grabs or hovers the object.

  1. Add it next to your interactable

    On an object that already has XR Grab Interactable (OpenXR) or Meta’s Grabbable and Hand Grab Interactable. Leave Backend on Auto.

  2. Choose when it fires

    Set Fire On to Select (while grabbed), Hover (while the hand is close) or Select And Hover.

  3. Choose fingers and strength

    Tick the fingers to press and set Strength, from 10 (barely there) to 60 (firm). Turn on Follow Grip to scale it by how far the fingers close, between Min Strength and Strength.

Make a surface feel like something — SpecialHaptics

Put it on a trigger collider and press Auto Find Hand Physics. Any finger that touches the collider feels the effect you pick in Type Of Haptics — no grab or hand-near check needed.

EffectFeels like
CustomHapticsConstant pressure while touched
CustomVibrationsVibration at a set frequency and strength
FountainEffectRunning water
RainDropEffectRaindrops on the palm
HeartBeatEffectA beating heart, regular or irregular
HandSqueezeEffectFires an event when the hand closes on the zone

For the two custom effects, set Haptic Pressure and, for vibration, Vibrations Frequency Value.

Objects your interactors don’t cover — ProximityCheck

It fires nothing itself: it tells HEXR the hand is near, so the object’s other haptics are let through. Add it with a trigger collider and press Auto Set Up.

Buttons pressed by a fingertip, finger-curl events and more: Which component do I need?

Trigger haptics from code

For game events, sequences, or anything the components don’t cover, call the hand’s Pressure Controller directly. Give your script a PressureTrackerMain field and drag in the scene’s Left or Right Pressure Controller.

One finger

csharp
// using HaptGlove; using HexR;
// hand: a PressureTrackerMain field with a Pressure Controller dragged in

// Pressure: finger, on/off, intensity 0.1-1, ramp speed 0.1-1, skip hand-near check
hand.CustomSingleHaptics(Haptics.Finger.Index, true, 0.5f, 1f, false);

// Vibration: finger, on/off, intensity 0.1-1, frequency 0.1-40 Hz, skip hand-near check
hand.CustomSingleVibrations(Haptics.Finger.Palm, true, 0.7f, 12f, false);

// The components' 10-60 strength scale, as the 0.1-1 intensity above
float intensity = PressureTrackerMain.StrengthToIntensity(30f);

The last argument skips the hand-near check. Pass true for presses that answer your own events rather than a touch.

Several fingers, same setting

Pass six on/off values, one per channel, always in the order Thumb, Index, Middle, Ring, Pinky, Palm. These calls have no skip argument, so they only fire while the hand is near something.

csharp
// One entry per channel: Thumb, Index, Middle, Ring, Pinky, Palm
bool[] grip = { true, true, true, false, false, false };   // thumb, index and middle

hand.TriggerCustomHapticsIncrease(grip, 0.6f, 1f);   // pressure 0.1-1, ramp speed 0.1-1
hand.TriggerCustomlVibrations(grip, 0.7f, 12f);      // intensity 0.1-1, frequency 0.1-40 Hz
                                                     // (the stray "l" is in the real name)

hand.TriggerAllHapticsIncrease(0.5f);                // every channel, pressure 0.1-1
hand.TriggerAllVibrations(12f);                      // every channel, frequency
hand.TriggerPinchPressure(0.6f);                     // thumb and index together

Each finger its own setting

Build one command for all six channels and send it straight to the glove: one Bluetooth write, with no hand-near check. Every array needs one entry per finger, in the same order, or the call throws an error.

csharp
HaptGloveHandler glove = HexRManager.Instance.rightHand;   // or leftHand

// All six channels, always in this order
Haptics.Finger[] fingers = { Haptics.Finger.Thumb,  Haptics.Finger.Index,
                             Haptics.Finger.Middle, Haptics.Finger.Ring,
                             Haptics.Finger.Pinky,  Haptics.Finger.Palm };
bool[]  on          = { true, true, true, true, true, true };   // false leaves a channel out
float[] intensities = { 0.3f, 0.9f, 0.9f, 0.6f, 0.4f, 0.8f };
float[] speeds      = { 1f,   1f,   1f,   1f,   1f,   1f   };
glove.BTSend(glove.haptics.HEXRPressure(fingers, on, intensities, speeds));

// Vibration: here frequency comes BEFORE intensity. 0 Hz is clamped to 0.1 Hz, not off.
float[] freqs = { 3f, 12f, 12f, 6f, 3f, 3f };
glove.BTSend(glove.haptics.HEXRVibration(fingers, on, freqs, intensities));

Letting go

csharp
hand.CustomSingleHaptics(Haptics.Finger.Index, false, 0f, 1f, true);    // one finger's pressure
hand.CustomSingleVibrations(Haptics.Finger.Palm, false, 0f, 12f, true);  // one finger's vibration
hand.RemoveIndexHaptics();      // one finger: RemoveThumbHaptics() ... RemovePalmHaptics()
hand.RemoveAllHaptics();        // every channel's pressure on this hand
hand.RemoveAllVibrations();     // every channel's vibration on this hand
glove.ReleaseAllChannels();     // everything on the glove, in one write
Release what you apply

The glove keeps applying the last pressure it was sent until it receives a release; nothing on the glove lets go by itself. From 0.9.4 the Unity package releases every channel when your app quits, pauses or disconnects the glove, but nothing can release it if the app crashes or the Bluetooth link drops, and the Python library releases nothing for you. If a glove is left pressing, switch the arm module off.

Release with true as the last argument, a Remove… call or ReleaseAllChannels(). A release that goes through the hand-near check is dropped once the hand has moved away — RemovePinchPressure() is one, so follow it with RemoveAllHaptics().

Whole scripts to copy: Press a finger on your own event and Press the finger that touches an object. Every method is listed under PressureTrackerMain.

Designing haptics

Two modes, and a few settings that change how they feel:

ModeSettingWhat it changes
PressureIntensity 0.1–1How hard it presses: about 15 to 50 kPa
PressureSpeed 0.1–1How fast it gets there. At 1, about 0.3 s to the firmest press; at 0.1, ten times slower
Vibration0.1–5 HzSeparate pulses you can count. Intensity sets how hard each one presses
Vibration5–40 HzA continuous buzz. Intensity sets how long each pulse lasts

For shaped rhythms there are also slow pulses and counted pulses — see Channels and parameters.

Tips