213 lines
6.6 KiB
C#
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;
|
|
}
|
|
}
|