using UnityEngine; using System.Collections; public class LightDistanceController : MonoBehaviour { public AnimationCurve LightCurveOn = AnimationCurve.EaseInOut(0, 0, 1, 1); public AnimationCurve LightCurveOff = AnimationCurve.EaseInOut(0, 1, 1, 0); public float GraphTimeMultiplier = 1f; // Czas trwania animacji public float TargetIntensity = 50f; // Docelowa intensywność światła public float ActivationDistance = 20f; // Odległość, przy której światło się włącza i wyłącza public Transform DistanceFrom; public bool DistanceFromMainCam; public bool DisableOnStart; public bool isFire; // Flaga kontrolująca efekty ognia public bool shadowOn = false; // Flaga kontrolująca cienie public float shadowActivationDistance = 5f; // Odległość włączania cieni // Parametry dla efektów ognia public float flickerSpeed = 0.1f; public float intensityMin = 0.5f; public float intensityMax = 1.5f; public float movementRadius = 0.1f; public float movementSpeed = 0.1f; private Light lightSource; private bool isLightEnabled; private bool isFading; private bool isFadeOutPending; private bool isFireReady; private float fadeStartTime; private float fadeDuration; private float fadeStartIntensity; private Vector3 initialPosition; private float randomOffset; private Camera mainCamera; private void Awake() { lightSource = GetComponent(); if (DistanceFromMainCam) { mainCamera = Camera.main; DistanceFrom = mainCamera?.transform; } if (DistanceFrom == null) { Debug.LogWarning("DistanceFrom is not set and DistanceFromMainCam is false, or Camera.main is not found."); } if (DisableOnStart) { lightSource.enabled = false; lightSource.intensity = 0; // Ustaw intensywność na 0, gdy światło jest wyłączone na starcie isLightEnabled = false; isFading = false; isFadeOutPending = false; } else { lightSource.intensity = 0; // Upewnij się, że światło zaczyna z intensywnością 0 } if (isFire) { initialPosition = lightSource.transform.position; randomOffset = Random.Range(0f, 100f); } // Ustawienia początkowe dla cieni lightSource.shadows = LightShadows.None; } private void Update() { CheckDistanceAndUpdateState(); if (isFire && isLightEnabled && isFireReady) { FlickerLight(); MoveLight(); } } private void CheckDistanceAndUpdateState() { if (DistanceFrom == null) return; float distanceSqr = (transform.position - DistanceFrom.position).sqrMagnitude; bool withinActivationDistance = distanceSqr <= ActivationDistance * ActivationDistance; if (withinActivationDistance) { if (!isLightEnabled && !isFading) { StartLightFade(true); } } else { if (isLightEnabled && !isFading && !isFadeOutPending) { isFadeOutPending = true; StartLightFade(false); } } // Manage shadow settings based on distance if (shadowOn && mainCamera != null) { float distanceFromCamera = Vector3.Distance(transform.position, mainCamera.transform.position); lightSource.shadows = distanceFromCamera <= shadowActivationDistance ? LightShadows.Soft : LightShadows.None; } } private void StartLightFade(bool fadeIn) { if (isFading) return; // Prevent multiple fade operations simultaneously fadeStartTime = Time.time; fadeDuration = GraphTimeMultiplier; fadeStartIntensity = lightSource.intensity; isFading = true; if (fadeIn) { lightSource.enabled = true; // Ensure light is enabled before fading in StartCoroutine(FadeLightIn()); } else { StartCoroutine(FadeLightOut()); } } private IEnumerator FadeLightIn() { float endIntensity = TargetIntensity; float elapsedTime = 0; while (elapsedTime < fadeDuration) { elapsedTime += Time.deltaTime; float normalizedTime = Mathf.Clamp01(elapsedTime / fadeDuration); lightSource.intensity = Mathf.Lerp(fadeStartIntensity, endIntensity, LightCurveOn.Evaluate(normalizedTime)); yield return null; } lightSource.intensity = TargetIntensity; // Ensure final intensity is set isLightEnabled = true; isFading = false; isFadeOutPending = false; // Reset this flag when light is fully on // Synchronize fire effect once the light reaches TargetIntensity if (isFire) { intensityMax = TargetIntensity; isFireReady = true; } } private IEnumerator FadeLightOut() { float endIntensity = 0; float elapsedTime = 0; while (elapsedTime < fadeDuration) { elapsedTime += Time.deltaTime; float normalizedTime = Mathf.Clamp01(elapsedTime / fadeDuration); lightSource.intensity = Mathf.Lerp(fadeStartIntensity, endIntensity, LightCurveOff.Evaluate(normalizedTime)); yield return null; } lightSource.intensity = 0; // Ensure final intensity is set // Only disable light after intensity is fully at 0 lightSource.enabled = false; isLightEnabled = false; isFading = false; isFadeOutPending = false; // Reset this flag when light is fully off // Disable fire effect if light is off if (isFire) { isFireReady = false; } } private void FlickerLight() { // Maintain intensity between min and max, synchronized with TargetIntensity if (isFireReady) { float noise = Mathf.PerlinNoise(Time.time * flickerSpeed, randomOffset); lightSource.intensity = Mathf.Lerp(intensityMin, intensityMax, noise); } } private void MoveLight() { float noiseX = Mathf.PerlinNoise(Time.time * movementSpeed, randomOffset) - 0.5f; float noiseY = Mathf.PerlinNoise(Time.time * movementSpeed, randomOffset + 1) - 0.5f; float noiseZ = Mathf.PerlinNoise(Time.time * movementSpeed, randomOffset + 2) - 0.5f; Vector3 movement = new Vector3(noiseX, noiseY, noiseZ) * movementRadius; lightSource.transform.position = initialPosition + movement; } }