using System.Collections.Generic; using UnityEngine; using UnityEngine.Rendering.Universal; [RequireComponent(typeof(Collider2D))] public class LightDimmer : MonoBehaviour { [Tooltip("Если не указан, будет использован Collider2D на этом же объекте.")] [SerializeField] private Collider2D targetCollider; [Tooltip("Тег игрока (используется для поиска Transform игрока)")] [SerializeField] private string playerTag; [Tooltip("Если хотите явно назначить конкретный Light2D для этого экземпляра, укажите его здесь (приоритет).")] [SerializeField] private Light2D[] lights; [Tooltip("Интенсивность света у минимального X (bounds.min.x)")] [SerializeField] private float startXIntensity; [Tooltip("Интенсивность света у максимального X (bounds.max.x)")] [SerializeField] private float endXIntensity; [Tooltip("Опционально: сглаживание изменения (0 мгновенно, >0 — скорость, единицы: интенсивность/сек)")] [SerializeField] [Min(0)] private float smoothing; private Transform playerTransform; // Храним все коллайдеры игрока, которые в данный момент пересекают триггер private readonly HashSet playerColliders = new HashSet(); private float boundsMinX; private float boundsMaxX; private void OnValidate() { if (targetCollider != null) { UpdateBounds(); } if (string.IsNullOrEmpty(playerTag)) playerTag = "Player"; } private void OnEnable() { if (targetCollider == null) targetCollider = GetComponent(); if (targetCollider != null) { UpdateBounds(); } if (string.IsNullOrEmpty(playerTag)) playerTag = "Player"; var playerObj = GameObject.FindGameObjectWithTag(playerTag); if (playerObj != null) playerTransform = playerObj.transform; } private void Start() { if (targetCollider == null) { targetCollider = GetComponent(); } UpdateBounds(); if (string.IsNullOrEmpty(playerTag)) playerTag = "Player"; } private void Update() { // Нужна ссылка на игрока и хотя бы один свет и collider if (!playerTransform || lights == null || lights.Length == 0 || targetCollider == null) return; // Проверяем, что игрок действительно внутри триггера (с учётом возможной множественной геометрии) bool playerInside = playerColliders.Count > 0; if (!playerInside) return; Vector3 playerPos = playerTransform.position; // Дополнительная страховка: проверяем AABB bounds if (!targetCollider.bounds.Contains(playerPos)) return; float playerX = playerPos.x; float t = 0f; if (!Mathf.Approximately(boundsMaxX, boundsMinX)) { t = Mathf.InverseLerp(boundsMinX, boundsMaxX, playerX); t = Mathf.Clamp01(t); } // Интерполируем интенсивность между startXIntensity и endXIntensity float desiredForPosition = Mathf.Lerp(startXIntensity, endXIntensity, t); for (int i = 0; i < lights.Length; i++) { var light2D = lights[i]; if (!light2D) continue; if (smoothing <= 0f) { light2D.intensity = desiredForPosition; } else { light2D.intensity = Mathf.MoveTowards(light2D.intensity, desiredForPosition, smoothing * Time.deltaTime); } } } private void OnTriggerEnter2D(Collider2D other) { if (!other.CompareTag(playerTag)) return; // Запоминаем коллайдер игрока playerColliders.Add(other); // Сохраняем Transform игрока (на случай, если раньше не найден) if (playerTransform == null) playerTransform = other.transform; } private void OnTriggerExit2D(Collider2D other) { if (!other.CompareTag(playerTag)) return; // Убираем коллайдер из множества; если множество пустое — игрок полностью вышел playerColliders.Remove(other); // Не затираем playerTransform, оставляем ссылку (чтобы можно было продолжать вычисления при следующем входе). // Если нужно — можно дополнительно реагировать на полное выход игрока (playerColliders.Count == 0). } private void UpdateBounds() { var b = targetCollider.bounds; boundsMinX = b.min.x; boundsMaxX = b.max.x; } void OnDrawGizmosSelected() { if (targetCollider == null) return; var b = targetCollider.bounds; Gizmos.color = Color.yellow; Gizmos.DrawLine(new Vector3(b.min.x, b.min.y, 0f), new Vector3(b.max.x, b.min.y, 0f)); Gizmos.DrawLine(new Vector3(b.max.x, b.min.y, 0f), new Vector3(b.max.x, b.max.y, 0f)); Gizmos.DrawLine(new Vector3(b.max.x, b.max.y, 0f), new Vector3(b.min.x, b.max.y, 0f)); Gizmos.DrawLine(new Vector3(b.min.x, b.max.y, 0f), new Vector3(b.min.x, b.min.y, 0f)); if (playerTransform != null) { Gizmos.color = Color.cyan; Vector3 p = playerTransform.position; Gizmos.DrawSphere(new Vector3(p.x, p.y, 0f), 0.05f); } } }