using System.Collections; using UnityEngine; using UnityEngine.Rendering; namespace MonoLimboStudio { public class LightFlicker : MonoBehaviour { [Header("Light Settings")] public Light targetLight; [Tooltip("Base intensity set externally (e.g. by ScarecrowFire). Flicker oscillates around this value.")] public float baseIntensity = 1f; [Tooltip("Flicker range applied relative to baseIntensity (e.g. 0.3 = ±30%).")] [Range(0f, 1f)] public float flickerRange = 0.3f; [Header("Perlin Flicker (smooth)")] public float flickerSpeed = 5f; [Header("Glitch Flicker (bursts)")] [Range(0f, 1f)] public float glitchChance = 0.15f; public float glitchMinDuration = 0.02f; public float glitchMaxDuration = 0.12f; [Header("Material Settings")] public Renderer targetRenderer; public string opacityProperty = "_Opacity"; [Range(0f, 1f)] public float minOpacity = 0.2f; [Range(0f, 1f)] public float maxOpacity = 1.0f; private Material _materialInstance; private float _randomOffset; // ───────────────────────────────────────────────────────────────────── void Start() { _randomOffset = Random.Range(0f, 1000f); if (targetRenderer != null) { _materialInstance = targetRenderer.material; if (!_materialInstance.HasProperty(opacityProperty)) Debug.LogWarning($"Property '{opacityProperty}' not found on material."); } StartCoroutine(FlickerRoutine()); } // ───────────────────────────────────────────────────────────────────── /// /// Sets the base intensity that the flicker oscillates around. /// Called each frame by ScarecrowFire as the fire grows. /// public void SetBaseIntensity(float value) { baseIntensity = value; } // ───────────────────────────────────────────────────────────────────── private IEnumerator FlickerRoutine() { while (true) { float perlinValue = Mathf.PerlinNoise(Time.time * flickerSpeed + _randomOffset, 0f); ApplyFlicker(perlinValue); if (Random.value < glitchChance) yield return StartCoroutine(GlitchBurst()); yield return null; } } private IEnumerator GlitchBurst() { float duration = Random.Range(glitchMinDuration, glitchMaxDuration); float elapsed = 0f; while (elapsed < duration) { ApplyFlicker(Random.value); elapsed += Time.deltaTime; yield return null; } } /// /// Applies flicker as an offset around baseIntensity rather than /// absolute min/max, so external intensity control stays intact. /// private void ApplyFlicker(float t) { if (targetLight != null) { float offset = Mathf.Lerp(-flickerRange, flickerRange, t); targetLight.intensity = Mathf.Max(0f, baseIntensity + offset); } if (_materialInstance != null && _materialInstance.HasProperty(opacityProperty)) _materialInstance.SetFloat(opacityProperty, Mathf.Lerp(minOpacity, maxOpacity, t)); } void OnDestroy() { if (_materialInstance != null) Destroy(_materialInstance); } } }