DualSense Adaptive Triggers

Author DualSense adaptive trigger effects as ScriptableObject data and play them through a single service call — no HID code, no per-pad wiring.

What the system is for

The DualSense controller's adaptive triggers are one of the most expressive feedback channels available to Unity developers, and one of the most tedious to implement. Reading the PS5 SDK documentation, wiring raw HID output reports, tracking per-device state so trigger updates never corrupt vibration — none of that belongs in game code.

Serenity's Feedback system includes a dedicated adaptive trigger channel that handles the HID layer on desktop and scaffolds the PS5 SDK path on console. You author the effect once as data, call IFeedbackService.Play, and the framework delivers it to the right pad.

The Unity problem

DualSense adaptive triggers require writing directly into the controller's USB HID output report. On desktop that means managing a shared output buffer that also carries rumble motors and LED data — update the trigger field carelessly and you blank the vibration state the frame before. On PS5 hardware the API is completely different: scePadSetTriggerEffect with ScePadTriggerEffectParam, licensed SDK headers that cannot travel with the repository, and a devkit to test on. Handling both paths in game code is a maintenance liability.

Beyond the transport layer, the effect model itself needs to be designer-accessible. Start position, end position, strength, trigger side, mode and duration all need inspector fields, range validation, and a way to combine with other feedback modalities in the same asset. Building that from scratch for every project is duplication that adds up.

How Serenity approaches it

Serenity models the effect as AdaptiveTriggerEffect with six fields: AdaptiveTriggerSide (Left, Right, or Both), AdaptiveTriggerMode (Off, Resistance, or Weapon), StartPosition01, EndPosition01, Strength01, DurationSeconds, and HaveExitTime. All normalized values run 0 to 1. The effect is authored in the inspector as AdaptiveTriggerEffectAuthoring inside a FeedbackDefinition ScriptableObject and converted to the pure effect at runtime.

At runtime AdaptiveTriggerChannel receives the effect and delegates to IAdaptiveTriggerBackend. On desktop the registered implementation is PcHidAdaptiveTriggerBackend, which translates the effect and sends it through the shared DualSenseOutputWriter — the same writer that manages vibration and LED state, so the three channels never overwrite each other. The default backend is NullAdaptiveTriggerBackend (a no-op) until a real backend is registered, meaning unsupported platforms simply do nothing without branching in game code.

How it fits into Serenity

The adaptive trigger feature sits inside Serenity's broader Feedback system. AdaptiveTriggerEffect and its enums live in the Serenity.Feedback.Application.Effects namespace — pure C# with no Unity dependencies. AdaptiveTriggerChannel implements IFeedbackChannel and lives in the infrastructure layer alongside the vibration, LED, screen shake and hit stop channels. The backend seam IAdaptiveTriggerBackend separates the channel from the transport: PcHidAdaptiveTriggerBackend for desktop USB HID, Ps5SdkAdaptiveTriggerBackend as a devkit scaffold for UNITY_PS5 builds, and NullAdaptiveTriggerBackend as the default no-op.

PcHidAdaptiveTriggerBackend maps each AdaptiveTriggerMode to the corresponding DualSense trigger effect: Resistance applies a continuous force from the start position, Weapon adds a break point between the start and end positions, and Off clears the effect. All writes go through DualSenseOutputWriter.TrySetTrigger, which keeps the per-device output in sync so vibration and LED state are never clobbered. When HaveExitTime is true the channel schedules a coroutine that resets the trigger after DurationSeconds (realtime); when HaveExitTime is false the effect persists until another effect — typically an Off-mode effect — overwrites it.

Practical workflow

  1. Create a FeedbackDefinition ScriptableObject and add an AdaptiveTriggerEffectAuthoring entry to its effects list.
  2. Set Side (Left, Right, or Both), Mode (Resistance or Weapon), StartPosition, EndPosition, Strength, DurationSeconds, and whether the effect should auto-reset via HaveExitTime.
  3. Register the FeedbackDefinition with the feedback service through the initialization pipeline.
  4. Play the effect at runtime by calling IFeedbackService.Play("your-id") or by dispatching a PlayFeedbackSignal from any system or UI element.
  5. To address a specific player's pad, pass a FeedbackTarget scoped to that player index or acting pad — the channel resolves the correct DualSense device automatically.
  6. To stop an active persistent effect before its natural exit, call IFeedbackService.Stop("your-id") or play an Off-mode effect on the same side.

What you get

  • AdaptiveTriggerEffect with AdaptiveTriggerSide (Left/Right/Both) and AdaptiveTriggerMode (Off/Resistance/Weapon)
  • Normalized 0–1 fields for StartPosition01, EndPosition01, and Strength01 — scaled by global feedback intensity
  • Timed auto-reset via HaveExitTime and DurationSeconds, or persistent mode until overwritten
  • PcHidAdaptiveTriggerBackend drives DualSense over USB HID on desktop and in the Unity editor
  • Shared DualSenseOutputWriter ensures trigger updates never corrupt vibration or LED state in the same output report
  • NullAdaptiveTriggerBackend default keeps unsupported platforms silent without any in-game branching
  • Ps5SdkAdaptiveTriggerBackend scaffold for UNITY_PS5 builds, ready for devkit completion
  • AdaptiveTriggerEffectAuthoring for inspector authoring inside FeedbackDefinition ScriptableObjects

When to use this

  • Games targeting PS5 or DualSense on PC that want weapon pull resistance, bow tension, or surface friction through the adaptive triggers.
  • Projects that already use Serenity's Feedback system for rumble, LED or screen shake and want to add adaptive triggers without a separate HID integration.
  • Teams that want designers to author trigger effects as data rather than coding controller output reports by hand.
  • Codebases that need the same feedback call to work across DualSense, DualShock 4 and other gamepads — the null backend handles non-DualSense devices silently.

Related systems

Use Serenity when you want DualSense adaptive triggers authored as data, delivered through the same feedback service that drives rumble and LED, and insulated from HID and SDK details on every platform.

Back to the home page