Files
HauntedBloodlines/Assets/Scripts/Lights/LightAnimationUpdate.cs
2025-05-29 22:31:40 +03:00

301 lines
11 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 System.Collections;
using System.Collections.Generic;
using UnityEngine;
[System.Serializable]
public class FlickeringLightData
{
public Light light;
public float maxIntensity;
}
[System.Serializable]
public class FlickeringRendererData
{
public Renderer renderer;
[Range(0f, 10f)]
public float flickerFactorMin = 1.2f;
[Range(0f, 10f)]
public float flickerFactorMax = 0.8f;
}
[RequireComponent(typeof(AudioSource))]
public class LightAnimationUpdate : MonoBehaviour
{
AudioSource lightFlickerAudioSource;
//AudioClip lightFlickerAudioClip;
AudioClip lightFlickerAudioClipForThisObject;
Animator _lightAnimator;
LightBulbEmissionUpdate _lightBulbEmissionUpdate;
public List<FlickeringLightData> flickeringLightsData; // List of Lights and their maxIntensity
public List<FlickeringRendererData> flickeringRenderersData; // List of Renderers and their maxIntensity
public float minIntensity = 0f;
public float flickerSpeed = 500f; // Adjust this to control the overall speed of flickering
public float intensityVariation = 0.1f; // Adjust this to control the strength of the flickering effect
public int flickerSetCount = 25; // Number of flickers in a set before the pause
public float flickerSetPause = 1.5f; // Duration of the pause between flicker sets
private List<float> originalLightIntensities = new List<float>();
private List<float> originalRendererIntensities = new List<float>();
private List<Texture> originalEmissiveMaps = new List<Texture>();
private Dictionary<Renderer, List<Material>> emissiveMaterialsMap = new Dictionary<Renderer, List<Material>>(); // Store emissive materials for each Renderer
[HideInInspector] public bool isFlickering = false;
private SanityActivation[] sanity;
private void Start()
{
lightFlickerAudioSource = GetComponent<AudioSource>();
lightFlickerAudioSource.loop = true;
lightFlickerAudioSource.spatialBlend = 1f;
lightFlickerAudioSource.maxDistance = 10f;
//lightFlickerAudioClip = Resources.Load<AudioClip>("LightSounds/LightFlickerLoop");
if (flickeringLightsData == null || flickeringLightsData.Count == 0)
{
Debug.LogError("FlickeringLightsAndEmission script needs a list of lights data to flicker!");
return;
}
// Store the original intensities of all lights
foreach (FlickeringLightData data in flickeringLightsData)
{
originalLightIntensities.Add(data.light.intensity);
}
// Store the original emissive maps and intensities of all renderers with emissive materials
foreach (FlickeringRendererData data in flickeringRenderersData)
{
Renderer renderer = data.renderer;
List<Material> emissiveMaterials = new List<Material>();
// Filter out materials with emissive maps
foreach (Material material in renderer.materials)
{
if (material.GetTexture("_EmissiveColorMap"))
{
emissiveMaterials.Add(material);
// Store the original emissive exposure weights for each material
originalRendererIntensities.Add(material.GetFloat("_EmissiveExposureWeight"));
}
}
emissiveMaterialsMap.Add(renderer, emissiveMaterials);
// Store the original emissive maps for each material
foreach (Material emissiveMaterial in emissiveMaterials)
{
originalEmissiveMaps.Add(emissiveMaterial.GetTexture("_EmissiveColorMap"));
}
}
try
{
// Get all components in the children of the transform
sanity = GetComponentsInChildren<SanityActivation>();
}
catch (System.Exception e)
{
// Handle exceptions here
Debug.LogError($"An error occurred: {e.Message}");
}
}
public void LightIsFlickering()
{
_lightAnimator.SetBool("IsFlickering", true);
if (!_lightAnimator.enabled) //If light animator is not enabled:
{
_lightAnimator.enabled = true; //Enable it.
}
if (!_lightBulbEmissionUpdate.UpdateEmission)
{
_lightBulbEmissionUpdate.UpdateEmission = true;
}
_lightBulbEmissionUpdate.IsFlickering = true;
}
public void LightIsNotFlickering()
{
_lightAnimator.SetBool("IsFlickering", false);
_lightBulbEmissionUpdate.ResetEmission();
if (!_lightAnimator.enabled) //If light animator is not enabled:
{
_lightAnimator.enabled = true; //Enable it.
}
_lightBulbEmissionUpdate.IsFlickering = false;
}
public void StartFlickering()
{
if (!isFlickering)
{
isFlickering = true;
//lightFlickerAudioSource.clip = lightFlickerAudioClip;
//lightFlickerAudioSource.Play();
RandomSoundsManager.GetInstance().PlayLightBussSound(lightFlickerAudioSource);
#region Sanity triggers
if (sanity.Length > 0)
{
foreach (var _sanity in sanity)
{
_sanity.DisableSanityTrigger();
}
}
#endregion
StartCoroutine(FlickerCoroutine());
}
}
public void StopFlickering()
{
if (isFlickering)
{
// Reset intensities of all lights to original values
for (int i = 0; i < flickeringLightsData.Count; i++)
{
if (flickeringLightsData[i] != null)
{
flickeringLightsData[i].light.intensity = originalLightIntensities[i];
}
}
// Reset intensities of all renderers to original values
for (int i = 0; i < flickeringRenderersData.Count; i++)
{
if (flickeringRenderersData[i] != null)
{
flickeringRenderersData[i].renderer.material.SetFloat("_EmissiveExposureWeight", originalRendererIntensities[i]);
}
}
// Reset emissive maps of all renderers to original values
for (int i = 0; i < flickeringRenderersData.Count; i++)
{
if (flickeringRenderersData[i] != null)
{
flickeringRenderersData[i].renderer.material.SetTexture("_EmissiveColorMap", originalEmissiveMaps[i]);
}
}
//Stop the flickering sound from all the lights
StopCoroutine(FlickerCoroutine());
StartCoroutine(StopAudioSourceAfterSeconds());
//lightFlickerAudioSource.clip = null;
//lightFlickerAudioSource.Stop();
#region Sanity triggers
if (sanity.Length > 0)
{
foreach (var _sanity in sanity)
{
_sanity.EnableSanityTrigger();
}
}
#endregion
isFlickering = false;
}
}
private IEnumerator FlickerCoroutine()
{
int flickerCount = 0;
while (isFlickering)
{
// 1. Υπολογίζουμε μία φορά το noise, κοινό για φως και emissive
float noise = Mathf.PerlinNoise(Time.time * flickerSpeed, 0f);
// 2. Υπολογισμός της νέας έντασης για τα φώτα
float flickerLightIntensity = Mathf.Lerp(minIntensity, flickeringLightsData[0].maxIntensity, noise * intensityVariation);
// 3. Εφαρμόζουμε την τιμή σε όλα τα φώτα
foreach (FlickeringLightData data in flickeringLightsData)
{
data.light.intensity = flickerLightIntensity;
}
// 4. Εφαρμόζουμε flicker στα emissive materials, με τον ίδιο ρυθμό (ίδιο noise)
foreach (FlickeringRendererData data in flickeringRenderersData)
{
Material[] materialsArray = data.renderer.materials;
foreach (var lightBulbRendMaterial in materialsArray)
{
int rendererIndex = flickeringRenderersData.IndexOf(data);
float originalEmissionIntensity = originalRendererIntensities[rendererIndex];
// Κρατάμε τον flicker παράγοντα πιο χαμηλό για να αποφεύγουμε υπερφωτισμούς
float flickerFactor = Mathf.Lerp(data.flickerFactorMin, data.flickerFactorMax, noise);
float flickerEmissionIntensity = originalEmissionIntensity * flickerFactor;
lightBulbRendMaterial.SetFloat("_EmissiveExposureWeight", flickerEmissionIntensity);
}
// Αν έχεις κάνει αλλαγές στα materials, ξαναπέρασέ τα
data.renderer.materials = materialsArray;
}
// 5. Διαχείριση flicker sets και παύσεων
flickerCount++;
if (flickerCount >= flickerSetCount)
{
flickerCount = 0; // reset
lightFlickerAudioSource.Stop();
yield return new WaitForSeconds(flickerSetPause);
float randomTime = Random.Range(0f, lightFlickerAudioSource.clip.length);
lightFlickerAudioSource.time = randomTime;
lightFlickerAudioSource.Play();
}
else
{
yield return new WaitForSeconds(0.1f); // μικρό delay ανά flicker
}
}
}
private IEnumerator StopAudioSourceAfterSeconds()
{
yield return new WaitForSeconds(0.1f);
lightFlickerAudioSource.Stop();
print("Stop light flickering audio source");
}
private Texture2D CreateFlickerEmissiveMap(Texture originalEmissiveMap, float flickeringIntensity)
{
// Copy the original emissive map to a new RenderTexture
RenderTexture renderTexture = new RenderTexture(originalEmissiveMap.width, originalEmissiveMap.height, 0);
Graphics.Blit(originalEmissiveMap, renderTexture);
// Set the active RenderTexture for writing
RenderTexture.active = renderTexture;
// Create a new Texture2D to store the modified emissive map
Texture2D flickerEmissiveMap = new Texture2D(originalEmissiveMap.width, originalEmissiveMap.height);
flickerEmissiveMap.ReadPixels(new Rect(0, 0, renderTexture.width, renderTexture.height), 0, 0);
flickerEmissiveMap.Apply();
// Apply brightness modification to each pixel in the emissive map
Color[] pixels = flickerEmissiveMap.GetPixels();
for (int i = 0; i < pixels.Length; i++)
{
pixels[i] *= flickeringIntensity;
}
flickerEmissiveMap.SetPixels(pixels);
flickerEmissiveMap.Apply();
// Clean up RenderTexture
RenderTexture.active = null;
renderTexture.Release();
return flickerEmissiveMap;
}
}