Danro/Assets/Resources/Scripts/Entities/LightActionsController.cs

144 lines
5.6 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using UnityEngine;
using UnityEngine.Rendering.Universal;
namespace RR.Common.Entities
{
public class LightActionsController : MonoBehaviour
{
public enum Mode { Blink, Pulse, Noise, Curve }
[Header("Target")]
[SerializeField] private Light light3D;
[SerializeField] private Light2D light2D;
[Tooltip("Доп. вариант — крутить эмиссию материала (опционально)")]
[SerializeField] private Renderer emissiveRenderer;
[SerializeField] private string emissionColorProperty = "_EmissionColor";
[Header("Mode")]
[SerializeField] private Mode mode = Mode.Blink;
[Header("Intensity")]
[SerializeField] private float minIntensity = 0f;
[SerializeField] private float maxIntensity = 1f;
[Header("Timings")]
[SerializeField] private float frequency = 2f; // Гц для Pulse/Noise, миганий/сек для Blink
[SerializeField, Range(0f, 1f)] private float duty = 0.2f; // Доля времени ON для Blink [0..1]
[SerializeField] private AnimationCurve curve = AnimationCurve.EaseInOut(0, 0, 1, 1);
[SerializeField] private bool useUnscaledTime = false;
[Header("Randomness (optional)")]
[SerializeField, Range(0f, 1f)] private float noiseAmplitude = 0.3f; // для Noise (0..1)
[SerializeField] private float noiseSpeed = 1.0f; // скорость «пламени»
[SerializeField] private Vector2 blinkJitter = new(-0.1f, 0.1f); // случайный сдвиг фазы Blink
[Header("Color (optional)")]
[SerializeField] private bool modulateColor = false;
[SerializeField] private Gradient colorOverCycle;
float baseIntensity;
float timer;
float blinkOffset;
Material _matInstance;
Color _baseEmission = Color.white;
void Reset()
{
light3D = GetComponent<Light>();
light2D = GetComponent<Light2D>();
emissiveRenderer = GetComponent<Renderer>();
}
void Awake()
{
if (light3D) baseIntensity = light3D.intensity;
if (light2D) baseIntensity = light2D.intensity;
if (emissiveRenderer && emissiveRenderer.sharedMaterial && _matInstance == null)
{
_matInstance = emissiveRenderer.material;
if (_matInstance.HasProperty(emissionColorProperty))
{
_baseEmission = _matInstance.GetColor(emissionColorProperty);
_matInstance.EnableKeyword("_EMISSION"); // на всякий
}
}
blinkOffset = Random.Range(blinkJitter.x, blinkJitter.y);
}
void Update()
{
float time = useUnscaledTime ? Time.unscaledTime : Time.time;
float deltaTime = useUnscaledTime ? Time.unscaledDeltaTime : Time.deltaTime;
timer += deltaTime;
float phase;
float k; // 0..1
switch (mode)
{
case Mode.Blink:
// пила с джиттером
phase = Mathf.Repeat((time + blinkOffset) * Mathf.Max(0.0001f, frequency), 1f);
k = phase < Mathf.Clamp01(duty) ? 1f : 0f;
break;
case Mode.Pulse:
// синус → 0..1
k = 0.5f * (1f + Mathf.Sin(time * Mathf.PI * 2f * frequency));
break;
case Mode.Noise:
// Perlin: базовый уровень + шум
float u = time * noiseSpeed;
float n = Mathf.PerlinNoise(u, 0.123f); // 0..1
float baseK = 0.5f * (1f + Mathf.Sin(time * Mathf.PI * 2f * frequency)); // мягкий пульс
k = Mathf.Clamp01(baseK * (1f - noiseAmplitude) + n * noiseAmplitude);
break;
case Mode.Curve:
// цикл 0..1 по частоте, кривой задаём форму
phase = Mathf.Repeat(time * Mathf.Max(0.0001f, frequency), 1f);
k = Mathf.Clamp01(curve.Evaluate(phase));
break;
default:
k = 1f; break;
}
float intensity = Mathf.Lerp(minIntensity, maxIntensity, k);
ApplyIntensity(intensity);
if (modulateColor && colorOverCycle != null)
{
ApplyColor(colorOverCycle.Evaluate(k));
}
}
void ApplyIntensity(float value)
{
if (light3D) light3D.intensity = value;
if (light2D) light2D.intensity = value;
if (_matInstance && _matInstance.HasProperty(emissionColorProperty))
{
// масштабируем эмиссию пропорционально интенсивности; цвет задайте через Gradient
Color c = _matInstance.GetColor(emissionColorProperty);
_matInstance.SetColor(emissionColorProperty, _baseEmission * value);
}
}
void ApplyColor(Color c)
{
if (light3D) light3D.color = c;
if (light2D) light2D.color = c;
if (_matInstance && _matInstance.HasProperty(emissionColorProperty))
_matInstance.SetColor(emissionColorProperty, c * Mathf.Max(0.0001f, _matInstance.GetColor(emissionColorProperty).maxColorComponent));
}
void OnDestroy()
{
if (_matInstance) Destroy(_matInstance);
}
}
}