Files
beyond/Assets/Scripts/LightDistanceController.cs
2024-11-20 15:21:28 +01:00

213 lines
6.6 KiB
C#

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<Light>();
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;
}
}