Screen Shake, Hit Stop y Screen Flash

Screen shake, camera shake, UI shake, hit stop y flash de pantalla completa — todo creado en un FeedbackDefinition y disparado con una única llamada al servicio.

Para qué sirve este sistema

El game feel vive en los detalles: el fotograma en que la cámara sacude con un golpe fuerte, la fracción de segundo de congelación que hace que el impacto se sienta real, el destello blanco que indica al jugador que acaba de ocurrir algo importante. Estos efectos son sencillos por separado, pero difíciles de coordinar. Cada uno afecta a un sistema distinto — la cámara, Time.timeScale, un canvas overlay — y todos necesitan ponerse de acuerdo sobre la intensidad, el timing y el estado de pausa.

Los canales de screen feedback de Serenity modelan cada efecto como un canal de primera clase que fluye por el mismo pipeline de IFeedbackService que el rumble del gamepad y los adaptive triggers. Un ScriptableObject FeedbackDefinition los mezcla todos. Una llamada a IFeedbackService.Play dispara el conjunto completo.

El problema en Unity

Implementar screen shake implica engancharse a la cámara activa en cada fotograma y aplicar un offset posicional que no luche con el controlador de cámara que ya esté en marcha. El hit stop implica bajar Time.timeScale sin romper un juego pausado. El screen flash implica crear un canvas overlay a pantalla completa y animar su alpha fuera del tiempo escalado para que siga siendo visible durante el stop. El UI shake implica encontrar todos los canvas raíz y desplazarlos en espacio de pantalla sin tocar los objetos en espacio mundo. Ninguno de esos problemas es difícil de forma aislada, pero cablearlos a una configuración de intensidad común, a un gestor de pausa global y a la misma superficie de edición requiere un esfuerzo real.

Sin una capa compartida, esos efectos suelen implementarse de forma ad hoc: una corrutina aquí, un helper estático allá, un número mágico incrustado en un script. El resultado son efectos que ignoran la configuración de intensidad global de accesibilidad, que luchan con el gestor de pausa o que dejan canvas huérfanos en la jerarquía.

Cómo lo aborda Serenity

Serenity define tres objetos de valor de efecto — ScreenFlashEffect (Color, PeakAlpha, DurationSeconds, AnimationCurve opcional), ScreenShakeEffect (Amplitude, Frequency, DurationSeconds) y UiScreenShakeEffect (misma forma que ScreenShakeEffect pero dirigido al espacio de UI) — y HitStopEffect (TargetTimeScale, DurationSeconds). Cada uno corresponde a un canal dedicado que se encarga del cableado específico de Unity: ScreenFlashChannel crea de forma diferida un canvas FeedbackScreenOverlay y lo gestiona con tiempo no escalado; ScreenShakeChannel adjunta automáticamente un UnityCameraShakeApplier a la cámara activa y la re-resuelve cada fotograma para sobrevivir a las transiciones de cámara; UiScreenShakeChannel descubre los canvas raíz a través de UiShakeRegistry y gestiona los componentes UnityUiShakeReceiver adjuntos a ellos de forma automática; HitStopChannel baja Time.timeScale y lo restaura, protegiendo contra conflictos con el gestor de pausa mediante IGameModeService.IsPaused.

Los cuatro efectos se crean dentro del mismo ScriptableObject FeedbackDefinition junto con rumble de gamepad, color LED y efectos de adaptive trigger. AnimationCurveFeedbackCurve envuelve UnityEngine.AnimationCurve detrás de una interfaz IFeedbackCurve para que la capa de Aplicación permanezca libre de tipos del motor. El camera shake y el UI shake escalan con el ajuste de intensidad global de IFeedbackSettings, dando a los jugadores un slider de accesibilidad para la intensidad visual. El hit stop ignora deliberadamente la intensidad global para que el timing de gameplay se mantenga determinista.

Cómo encaja en Serenity

El screen feedback vive en el namespace Serenity.Feedback y sigue la estructura por capas de la foundation. La capa de Aplicación define ScreenFlashEffect, ScreenShakeEffect, UiScreenShakeEffect y HitStopEffect como objetos de datos simples, IFeedbackCurve como abstracción de envolvente, e IFeedbackService como punto de disparo único. La capa de Infraestructura proporciona las implementaciones de canal de Unity: ScreenFlashChannel, ScreenShakeChannel, UiScreenShakeChannel y HitStopChannel, más el MonoBehaviour FeedbackScreenOverlay, UnityCameraShakeApplier y UnityUiShakeReceiver. FeedbackDefinition es el ScriptableObject que contiene la lista de efectos creada y que UnityFeedbackDefinitionProvider resuelve en tiempo de ejecución.

El screen feedback coopera con otros tres sistemas de Serenity. El agregado de UI proporciona el descubrimiento de canvas raíz que UiScreenShakeChannel usa a través de UiShakeRegistry. Game Mode proporciona el estado de pausa que HitStopChannel comprueba antes de bajar timeScale. El Event Dispatcher permite que cualquier sistema dispare un PlayFeedbackSignal sin depender directamente de IFeedbackService, para que los diseñadores puedan conectar el feedback a eventos de juego en el inspector sin tocar el código.

Flujo de trabajo práctico

  1. Crea un asset ScriptableObject FeedbackDefinition en tu proyecto.
  2. Añade un ScreenShakeEffect, UiScreenShakeEffect, ScreenFlashEffect o HitStopEffect — o cualquier combinación — a la lista de efectos.
  3. Establece los valores de amplitud, frecuencia, duración y color directamente en el inspector; opcionalmente asigna un AnimationCurveFeedbackCurve para dar forma a la envolvente.
  4. Registra la definición con el servicio de feedback a través de la pipeline de inicialización.
  5. Llama a IFeedbackService.Play("tu-id-de-definición") desde código, o conecta un PlayFeedbackSignal a un binding del Event Dispatcher para dispararlo sin código.
  6. Ajusta el parámetro de intensidad global en IFeedbackSettings para escalar el camera shake y el UI shake en todas las definiciones a la vez para accesibilidad.

Qué incluye

  • ScreenFlashEffect — destello RGB a pantalla completa con PeakAlpha y AnimationCurve opcional, gestionado con tiempo no escalado para que sea visible durante el hit stop
  • ScreenShakeEffect — vibración posicional de cámara con Amplitude, Frequency y DurationSeconds; offset aplicado de forma aditiva para sobrevivir a cualquier controlador de cámara
  • UiScreenShakeEffect — canal de shake de UI/HUD/menú independiente en espacio de pantalla, separado del camera shake para que menús y cámara mundo no entren en conflicto
  • HitStopEffect — bajada breve de Time.timeScale con TargetTimeScale y DurationSeconds; consciente de pausa y excluido deliberadamente del escalado de intensidad global
  • ScreenFlashChannel — instancia de forma diferida un canvas FeedbackScreenOverlay; sin configuración manual necesaria
  • ScreenShakeChannel — adjunta automáticamente UnityCameraShakeApplier a la cámara activa y la re-resuelve cada fotograma para mayor seguridad en transiciones de cámara
  • UiScreenShakeChannel — descubre automáticamente los canvas raíz mediante UiShakeRegistry y adjunta UnityUiShakeReceiver sin cableado manual
  • Un único ScriptableObject FeedbackDefinition mezcla efectos de pantalla con rumble de gamepad, LED y efectos de adaptive trigger; un IFeedbackService.Play los dispara todos

Cuándo usarlo

  • Juegos que necesitan reacciones de impacto contundentes — combate cuerpo a cuerpo, disparos, explosiones — y quieren que el screen shake, el flash y el hit stop se disparen como un conjunto coordinado.
  • Proyectos que ya usan el sistema Feedback de Serenity para el rumble del gamepad y quieren extender las mismas definiciones para cubrir efectos de pantalla sin código adicional.
  • Equipos que quieren que los efectos de intensidad visual respeten un ajuste de accesibilidad para que los jugadores puedan reducir o desactivar el shake y el flash de forma global.
  • Bases de código donde los diseñadores necesitan ajustar y disparar efectos de feedback desde el inspector sin modificar scripts.

Sistemas relacionados

Usa el screen feedback de Serenity cuando quieras que el camera shake, el UI shake, el screen flash y el hit stop convivan en el mismo ScriptableObject, escalen con un único slider de accesibilidad y se disparen con una sola llamada al servicio — sin tocar directamente el controlador de cámara, la jerarquía de canvas ni Time.timeScale.

Volver a la página principal