Skip to content
EN

Integrating into Your Project

Once you have completed Getting Started, you are ready to integrate the SDK into your own project.

Real-world examples of haptic wiring patterns are available in the Showcase sample.

Import Showcase from the Samples tab in Package Manager → open Showcase.unity and press Play. See Showcase Sample for details.


Integration follows two broad stages. This page gives an overview; each section links to the dedicated page for details.

  1. Wiring — Connect in-game events to the haptic feedback you want to play
  2. Tuning — Configure the playback mode (Fire / Clip), intensity, target device, and dynamic modulation

This stage connects in-game events (button clicks, collisions, Animator state transitions, etc.) to entries in the EventMap (the haptic feedback to play).

Run Hapbeat → Initial Scene Setup from the menu bar. This creates the following in one step:

  • Assets/HapbeatSDK/ folder layout (Kits / EventMaps / Scenes)
  • [Hapbeat Event Router] GameObject (contains the HapbeatManager singleton)
  • Assets/HapbeatSDK/EventMaps/<scene-name>-EventMap.asset
  • Opens the Event Map window with the new asset selected

Running it again on an already-configured scene is safe — the existing Router and EventMap are reused without duplication. For individual operations such as “add only the Router” or “add only the EventMap”, see Editor Menu Reference.

unity-eventmap

Open Hapbeat → Open Event Map and click + Add Event to add entries (opening the window alone does not create an asset — the asset from step 1-1 is assumed to exist).

Key fields (frequently used fields only; see EventMap Window for the full list including loop, bindings, delayOffsetSeconds, notes, and manifestOverride):

FieldDescription
NameHuman-readable label for display in the Editor
ModeFIRE (Command) — play device-stored audio by ID
CLIP (Stream Clip) — send a Unity AudioClip as PCM
Event IDThe command to send
ClipThe AudioClip to send in StreamClip mode
GainVibration intensity (0.0–2.0, multiplied against the Kit manifest intensity)
TargetingDestination (empty = all devices; player_1 / */pos_neck / player_1/pos_chest, etc.)

Configure when during gameplay each entry is invoked. There are three approaches — choose based on your project’s scale, team composition, and existing code (combining them is also fine).

A. Via components / Behaviours (wired in Inspector)

Section titled “A. Via components / Behaviours (wired in Inspector)”

Attach a Hapbeat Trigger component (or HapbeatStateBehaviour) to a GameObject and select the EventMap entry in the Inspector. No code required. Zones Z1–Z5 in the Showcase sample each demonstrate a different pattern.

Component / BehaviourUse caseReference Showcase Zone
HapbeatCollisionTriggerPhysics collision / Trigger Enter / Exit. VelocityScaled links intensity to impact forceZ1 Bowling (6 Pins set up via BatchSetup)
HapbeatStateBehaviourFires on Animator state Enter/Exit. Attach directly to a state as a StateMachineBehaviourZ2 Door (attached to Open / Closed states)
HapbeatSequenceTriggerManages Grab / Hold / Release in a single componentZ3 Fishing (Sequence + ParameterBinding)
HapbeatTickEmitterSnap-fires based on the magnitude of change in a continuous value (Slider, etc.)Z4 Stream Console (Slider via BatchSetup)
HapbeatUnityEventTriggerCalls Fire() from any UnityEvent. Button / XR Interactable / Animation Event, etc.Z5 Charge (TargetReceiver.OnHit → Fire)

Component details: Trigger Components

B. Call Trigger from script (via EventMap)

Section titled “B. Call Trigger from script (via EventMap)”

Hold a Trigger reference in your script and call trigger.Fire() from game logic. Because it goes through an EventMap entry, gain / target / latency / manifest intensity compensation all apply automatically. Writing to GainMultiplier every frame enables dynamic modulation.

public class ChargeShooter : MonoBehaviour
{
[SerializeField] private HapbeatUnityEventTrigger _trigger;
[SerializeField] private AnimationCurve _gainCurve;
void Release(float chargeT) {
_trigger.GainMultiplier = _gainCurve.Evaluate(chargeT);
_trigger.Fire();
}
}

Reference implementation: Showcase Z5 ChargeShooter (Samples~/Showcase/Scripts/ChargeShooter.cs).

The distinction from A is whether the firing condition is fully expressible as an Inspector declaration or requires calculation in script logic. Both approaches can coexist.

C. Call Manager.Play() directly, bypassing EventMap (special cases)

Section titled “C. Call Manager.Play() directly, bypassing EventMap (special cases)”

A direct path exists via HapbeatManager without going through EventMap.

HapbeatManager.Instance?.Play("my-kit.enemy_hit", gain: 0.8f);

This path loses the advantages of EventMap-based management (designers can adjust values in the Inspector, the full wiring list is visible, latency compensation applies automatically, etc.). Reserve it for situations where EventMap cannot scale to the required volume or dynamic nature.

For example: managing heartbeats for 100 players individually with per-player IDs. Statically enumerating them in EventMap would require hundreds of entries and make GUI management impractical; additionally, Event IDs must be constructed dynamically at runtime (Play($"heartbeat.player_{id}")). That combination is where C is appropriate.


Once wiring is in place, design the playback mode, intensity, and target device for each entry. Most settings are edited in EventMap Window. This page gives an overview; follow the links for details.

2-1. Choose Fire (Command) or Clip (StreamClip)

Section titled “2-1. Choose Fire (Command) or Clip (StreamClip)”

Select via the Mode field on the EventMap entry:

  • Fire (Command) — Invokes a Kit already deployed to the device by ID. Low latency; sends only a short command.
  • Clip (StreamClip) — Sends a Unity AudioClip via UDP for playback. No Kit deployment needed; dynamic modulation supported.

Starting with Clip for rapid prototyping, then switching to Fire once the design is finalized, is the recommended workflow. Decision criteria: Fire vs. Clip — When to Use Each.

  • Gain acts as a multiplier against the intensity in the Kit manifest (the reference vibration intensity set when designing the Kit in Hapbeat Studio). 1.0 plays at the manifest level; 0.5 plays at half. See Build and Distribute a Kit for details on the gain hierarchy.
  • Target specifies the destination device. Empty = all devices; player_1 = a specific player; */pos_neck = the neck position on all players; player_1/pos_chest = a specific player + body position, etc. See the contracts addressing spec for the full reference.

2-3. Dynamic modulation (Parameter Binding / script)

Section titled “2-3. Dynamic modulation (Parameter Binding / script)”

A mechanism for writing gain / pan on every frame during StreamClip playback so it tracks game state (movement, velocity, distance, etc.).

  • Parameter Binding — Declaratively map Transform / Rigidbody / Slider etc. to gain / pan in the Inspector (Showcase Z3 / Z4)
  • Script — Write trigger.GainMultiplier = curve(t) every frame (Showcase Z5)

Details and guidance: Parameter Binding