using UnityEngine; public class GlobalMonochromeRuntimeController : MonoBehaviour { public static GlobalMonochromeRuntimeController Instance { get; private set; } [Header("Runtime Monochrome Defaults")] public float defaultEnterDuration = 0.12f; public float defaultRecoverDuration = 0.12f; public bool useUnscaledTime = true; public bool triggerOnEnable = false; private static float sRuntimeIntensity; private float enterDuration; private float recoverDuration; private float elapsed; private Phase phase = Phase.None; public static float RuntimeIntensity => Mathf.Clamp01(sRuntimeIntensity); private enum Phase { None, Enter, Exit } private void Awake() { if (Instance == null) { Instance = this; return; } if (Instance != this) Destroy(gameObject); } private void OnEnable() { if (triggerOnEnable) TriggerMonochrome(); } private void Update() { float delta = useUnscaledTime ? Time.unscaledDeltaTime : Time.deltaTime; UpdateWave(delta); } public void TriggerMonochrome() { TriggerMonochrome(defaultEnterDuration, defaultRecoverDuration); } public void TriggerMonochrome(float enterDurationSeconds, float recoverDurationSeconds) { enterDuration = Mathf.Max(0.0001f, enterDurationSeconds); recoverDuration = Mathf.Max(0.0001f, recoverDurationSeconds); elapsed = 0f; phase = Phase.Enter; sRuntimeIntensity = 0f; } private void UpdateWave(float delta) { if (phase == Phase.None) { sRuntimeIntensity = 0f; return; } elapsed += delta; if (phase == Phase.Enter) { float normalized = Mathf.Clamp01(elapsed / enterDuration); sRuntimeIntensity = Mathf.LerpUnclamped(0f, 1f, normalized); if (normalized < 1f) return; sRuntimeIntensity = 1f; elapsed = 0f; phase = Phase.Exit; return; } float exitNormalized = Mathf.Clamp01(elapsed / recoverDuration); sRuntimeIntensity = Mathf.LerpUnclamped(1f, 0f, exitNormalized); if (exitNormalized < 1f) return; sRuntimeIntensity = 0f; phase = Phase.None; } public static GlobalMonochromeRuntimeController EnsureInstance() { if (Instance != null) return Instance; GlobalMonochromeRuntimeController existing = FindFirstObjectByType(); if (existing != null) { Instance = existing; return existing; } GameObject runtimeObject = new GameObject("__global_monochrome_runtime"); Instance = runtimeObject.AddComponent(); return Instance; } public static void Trigger(float enterDurationSeconds, float recoverDurationSeconds) { EnsureInstance().TriggerMonochrome(enterDurationSeconds, recoverDurationSeconds); } public static void TriggerDefault() { EnsureInstance().TriggerMonochrome(); } }