Momo-Space-Diner-Code-Repo / AudioVisualizers / MultiSourceAudioVisualizerMaterialsColorGradient.cs
MultiSourceAudioVisualizerMaterialsColorGradient.cs
Raw
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class MultiSourceAudioVisualizerMaterialsColorGradient : MonoBehaviour
{
    public GameObject visualizationPrefab; // Prefab for visualizer bars
    public float smoothingSpeed = 5f; // Controls how fast the visualizer responds
    private float[] spectrumData = new float[256]; // Raw spectrum data
    private float[] smoothedSpectrumData = new float[256]; // Smoothed spectrum data
    public float visualizerScale = 5f; // Controls how much the bars scale
    public float spacing = 1f; // Spacing between visualizer bars
    public Gradient spectrumGradient; // Gradient for smooth color transitions
    public string materialColorProperty = "_Color"; // Material color property to modify
    public string materialEmissionProperty = "_EmissionColor"; // Emission property to modify
    public float maxEmissionIntensity = 4f; // Maximum emission intensity for low frequencies
    public float minEmissionIntensity = 1f; // Minimum emission intensity for high frequencies
    private List<GameObject> visualizers = new List<GameObject>(); // Dynamically managed visualizer objects

    void Start()
    {
        UpdateVisualizerCount(); // Ensure the visualizers match the spectrum data count on start
    }

    void Update()
    {
        UpdateSpectrumData();
        UpdateVisualizers();
    }

    void UpdateSpectrumData()
    {
        // Reset spectrumData to zero at the start of each frame
        for (int i = 0; i < spectrumData.Length; i++)
        {
            spectrumData[i] = 0f;
        }

        // Find all AudioSource objects in the scene
        AudioSource[] audioSources = FindObjectsOfType<AudioSource>();

        // Accumulate spectrum data from all audio sources
        foreach (AudioSource audioSource in audioSources)
        {
            if (audioSource.isPlaying && !audioSource.mute)
            {
                float[] tempSpectrum = new float[spectrumData.Length];
                audioSource.GetSpectrumData(tempSpectrum, 0, FFTWindow.Rectangular);

                for (int i = 0; i < spectrumData.Length; i++)
                {
                    spectrumData[i] += tempSpectrum[i];
                }
            }
        }
    }

    void UpdateVisualizerCount()
    {
        // Adjust the number of visualizer objects to match the spectrum data count
        while (visualizers.Count < spectrumData.Length)
        {
            GameObject newVisualizer = Instantiate(visualizationPrefab, transform);
            visualizers.Add(newVisualizer);
        }

        while (visualizers.Count > spectrumData.Length)
        {
            GameObject toRemove = visualizers[visualizers.Count - 1];
            visualizers.RemoveAt(visualizers.Count - 1);
            Destroy(toRemove);
        }

        // Position the visualizers in a straight line near the parent
        for (int i = 0; i < visualizers.Count; i++)
        {
            visualizers[i].transform.localPosition = new Vector3(i * spacing, 0, 0);
        }
    }

    void UpdateVisualizers()
    {
        for (int i = 0; i < visualizers.Count; i++)
        {
            if (i >= spectrumData.Length) break;

            // Smooth out the spectrum data
            smoothedSpectrumData[i] = Mathf.Lerp(smoothedSpectrumData[i], spectrumData[i], Time.deltaTime * smoothingSpeed);

            // Scale the visualizer bars based on the smoothed spectrum data
            float newYScale = Mathf.Lerp(0.1f, visualizerScale, smoothedSpectrumData[i] * 100); // Adjust scaling factor as needed
            Vector3 newScale = visualizers[i].transform.localScale;
            newScale.y = newYScale;
            visualizers[i].transform.localScale = newScale;

            // Update material properties with gradient color
            Renderer renderer = visualizers[i].GetComponent<Renderer>();
            if (renderer != null)
            {
                Material material = renderer.material;

                // Calculate the normalized position in the visualizer array
                float normalizedPosition = (float)i / (visualizers.Count - 1); // Maps `i` to a range [0, 1]

                // Get the color from the gradient based on normalized position
                Color gradientColor = spectrumGradient.Evaluate(normalizedPosition);

                // Adjust emission intensity based on frequency range
                float emissionMultiplier = Mathf.Lerp(maxEmissionIntensity, minEmissionIntensity, normalizedPosition);

                // Adjust intensity using smoothed spectrum data
                Color finalColor = gradientColor * Mathf.Clamp01(smoothedSpectrumData[i] * 10f);

                // Set material color and emission
                material.SetColor(materialColorProperty, finalColor);
                material.SetColor(materialEmissionProperty, finalColor * emissionMultiplier);

                // Enable emission (if not already enabled)
                material.EnableKeyword("_EMISSION");
            }
        }
    }
}