Rumble de Gamepad e Iluminación de Mando

Un único servicio de feedback que controla el rumble de doble motor, el color del lightbar LED y la vibración HD del Switch Pro en PS5, PS4, Nintendo Switch Pro y mandos genéricos.

Para qué sirve este sistema

El output de gamepad en Unity parece sencillo hasta que se publica en una segunda plataforma. SetMotorSpeeds borra el color del lightbar. SetLightBarColor cancela la salida del motor. El output por Bluetooth es silenciosamente inerte en los mandos PlayStation. La vibración HD del Switch Pro y el LED del botón Home no tienen ninguna API en Unity. Cualquier equipo que haya publicado un juego con mando ha encontrado al menos uno de estos bugs.

El sistema Feedback de Serenity gestiona el informe HID completo de cada familia de mandos y expone todo a través de un único IFeedbackService. Se pueden reproducir efectos por id, dirigirlos a jugadores o dispositivos concretos, escalar la intensidad globalmente desde los ajustes y disparar cualquier efecto sin código a través del Event Dispatcher, sin tener que tocar los detalles del driver de cada plataforma.

El problema en Unity

La API Gamepad de Unity expone SetMotorSpeeds y SetLightBarColor como dos llamadas separadas, pero el mando recibe en realidad un único informe de salida compartido. Escribir las velocidades del motor sobreescribe el lightbar y viceversa. Además, el path de output de Unity es inerte por Bluetooth en DualSense y DualShock 4, y la vibración HD del Switch Pro está completamente ausente de la API de Unity. Los proyectos que necesitan tanto rumble como feedback LED en más de una plataforma acaban escribiendo parches frágiles por plataforma que se rompen en cada actualización de Unity.

Los juegos multijugador se enfrentan a un segundo problema: Gamepad.current es ambiguo cuando hay varios mandos conectados. Saber qué mando físico disparó la última acción —y por tanto cuál debe vibrar— requiere un seguimiento explícito del dispositivo activo. Sin eso, el rumble o bien se reproduce en el mando equivocado o se desactiva por completo para evitar el bug.

Cómo lo aborda Serenity

IFeedbackService es el punto de entrada único: Play(id) dispara un efecto por id en el dispositivo activo, PlayForPlayer(playerIndex, id) y PlayForDevice(deviceId, id) se dirigen a objetivos concretos, PlayForPlayerInput(playerInput, id) se integra con el componente PlayerInput de Unity, StopAll() cancela los efectos activos, y SetGlobalEnabled(bool) y SetGlobalIntensity(float) aplican los ajustes de accesibilidad en tiempo real. Los efectos se despachan a implementaciones de IFeedbackChannel: VibrationChannel gestiona el rumble de doble motor mediante VibrationEffect (amplitud baja y alta de forma independiente), y LedChannel gestiona el color del lightbar mediante LedEffect.

El direccionamiento multijugador se gestiona mediante FeedbackTarget, que puede representar el mando activo, un índice de jugador o un id de dispositivo. UnityGamepadTargetResolver mapea esos objetivos a dispositivos físicos, e IActingDeviceTracker registra qué gamepad conectado disparó la última acción, eliminando la ambigüedad de Gamepad.current. FeedbackScaler lee vibration_enabled y vibration_intensity de GameSettings y los aplica en tiempo real para que las preferencias de accesibilidad surtan efecto sin necesidad de reiniciar los efectos.

Cómo encaja en Serenity

El sistema Feedback vive en el namespace Serenity.Feedback y sigue la estructura por capas de la foundation. La capa Business define IFeedbackService, IFeedbackChannel, IFeedbackEffect, FeedbackTarget, VibrationEffect, LedEffect y FeedbackScaler detrás de interfaces estables. La capa Unity proporciona los backends HID: DualSenseOutputWriter para PS5, DualShock4OutputWriter para PS4 y SwitchProVibrationService para la vibración HD del Nintendo Switch Pro, transmitida en un hilo en segundo plano a aproximadamente 100 Hz. Los mandos genéricos utilizan como fallback el Gamepad.SetMotorSpeeds de Unity. La capa HID incluye RawHidDevice y GamepadHidrawTransport para el acceso directo al dispositivo, además de GamepadHardwareIds, que identifica cada familia de mando compatible, con el tratamiento adicional que los mandos PlayStation requieren por Bluetooth. Este sistema es solo de salida — la entrada de movimiento por giroscopio y acelerómetro de esos mismos DualSense, DualShock 4 y Switch Pro vive en el sistema Player Input.

La compatibilidad de plataformas abarca Windows (USB mediante ExecuteCommand, Bluetooth mediante HID raw), Linux (todo el output mediante hidraw, con reglas udev necesarias) y macOS (solo USB). La autoría utiliza ScriptableObjects de FeedbackDefinition que agrupan efectos y se referencian por id. Los disparos sin código están disponibles mediante PlayFeedbackSignal a través del Event Dispatcher. El sistema coopera con PlayerInput para la resolución de jugadores y dispositivos, con GameSettings para el escalado de intensidad en tiempo real y con el Event Dispatcher para los disparos basados en señales.

Flujo de trabajo práctico

  1. Crea un ScriptableObject FeedbackDefinition y añade entradas VibrationEffect y LedEffect con las amplitudes y colores que necesites.
  2. Asigna la definición al proyecto y referénciala por su id donde quieras disparar el feedback.
  3. Deja que el instalador de feedback registre IFeedbackService y todos los canales a través de la pipeline de inicialización.
  4. Usa IActingDeviceTracker para saber qué gamepad disparó la última acción y resuélvelo a través de FeedbackTarget.
  5. Llama a IFeedbackService.Play(id) desde el código de gameplay o despacha PlayFeedbackSignal desde el Event Dispatcher para disparos sin código.
  6. Configura vibration_enabled y vibration_intensity en GameSettings para que FeedbackScaler aplique las preferencias de accesibilidad en tiempo real.

Qué incluye

  • Punto de entrada único IFeedbackService con Play, PlayForPlayer, PlayForDevice, PlayForPlayerInput, StopAll, SetGlobalEnabled y SetGlobalIntensity
  • VibrationEffect con control independiente del motor de baja amplitud y alta amplitud despachado mediante VibrationChannel
  • LedEffect para el color RGB del lightbar despachado mediante LedChannel
  • Gestión completa del informe HID: DualSenseOutputWriter (PS5), DualShock4OutputWriter (PS4), SwitchProVibrationService (Switch Pro)
  • Soporte Bluetooth mediante una capa de HID raw para mandos PlayStation
  • Vibración HD del Switch Pro transmitida en un hilo en segundo plano a ~100 Hz más LED monocromo del botón Home
  • Direccionamiento multijugador mediante FeedbackTarget, UnityGamepadTargetResolver e IActingDeviceTracker
  • FeedbackScaler conectado a vibration_enabled y vibration_intensity de GameSettings para control de accesibilidad en tiempo real
  • Disparo sin código mediante PlayFeedbackSignal a través del Event Dispatcher

Cuándo usarlo

  • Proyectos que necesitan output de rumble y LED en PS5, PS4 o Nintendo Switch Pro y han encontrado el bug de sobreescritura motor/lightbar de Unity.
  • Juegos que se publican en Linux o que necesitan output de gamepad por Bluetooth que el path por defecto de Unity no entrega.
  • Juegos multijugador que deben vibrar el mando correcto cuando hay varios gamepads conectados.
  • Bases de código que quieren control global de intensidad y activación compatible con la accesibilidad sin condicionales por cada punto de uso.

Sistemas relacionados

Usa el sistema Feedback de Serenity cuando necesites un output de gamepad fiable en distintas familias de mandos y plataformas, con una única llamada a un servicio como único punto de integración que el código de gameplay necesita conocer.

Volver a la página principal