96 lines
3.0 KiB
C#
96 lines
3.0 KiB
C#
using System.Collections;
|
|
using UnityEngine;
|
|
|
|
namespace MonoLimboStudio
|
|
{
|
|
public class LightFlicker : MonoBehaviour
|
|
{
|
|
[Header("Light Settings")]
|
|
public Light targetLight;
|
|
public float minIntensity = 0.5f;
|
|
public float maxIntensity = 1.5f;
|
|
|
|
[Header("Perlin Flicker (smooth)")]
|
|
public float flickerSpeed = 5f;
|
|
|
|
[Header("Glitch Flicker (bursts)")]
|
|
[Range(0f, 1f)] public float glitchChance = 0.15f; // probability of a glitch burst each frame
|
|
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()
|
|
{
|
|
// unique offset per instance so lamps don't flicker in sync
|
|
_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());
|
|
}
|
|
|
|
private IEnumerator FlickerRoutine()
|
|
{
|
|
while (true)
|
|
{
|
|
// --- Smooth Perlin phase ---
|
|
float perlinValue = Mathf.PerlinNoise(Time.time * flickerSpeed + _randomOffset, 0f);
|
|
ApplyFlicker(perlinValue);
|
|
|
|
// --- Random glitch burst (occasional) ---
|
|
if (Random.value < glitchChance)
|
|
{
|
|
yield return StartCoroutine(GlitchBurst());
|
|
}
|
|
|
|
yield return null; // wait for next frame
|
|
}
|
|
}
|
|
|
|
private IEnumerator GlitchBurst()
|
|
{
|
|
float duration = Random.Range(glitchMinDuration, glitchMaxDuration);
|
|
float elapsed = 0f;
|
|
|
|
while (elapsed < duration)
|
|
{
|
|
// fully random intensity during the burst
|
|
float glitchValue = Random.value;
|
|
ApplyFlicker(glitchValue);
|
|
|
|
elapsed += Time.deltaTime;
|
|
yield return null;
|
|
}
|
|
}
|
|
|
|
private void ApplyFlicker(float t)
|
|
{
|
|
if (targetLight != null)
|
|
targetLight.intensity = Mathf.Lerp(minIntensity, maxIntensity, t);
|
|
|
|
if (_materialInstance != null && _materialInstance.HasProperty(opacityProperty))
|
|
_materialInstance.SetFloat(opacityProperty, Mathf.Lerp(minOpacity, maxOpacity, t));
|
|
}
|
|
|
|
void OnDestroy()
|
|
{
|
|
// .material creates a new instance — destroy it to avoid memory leaks
|
|
if (_materialInstance != null)
|
|
Destroy(_materialInstance);
|
|
}
|
|
}
|
|
} |