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

public class MultiSourceAudioVisualizerMaterialsSingular : MonoBehaviour
{
    public GameObject[] Visualizer; // Array of visualizer bars or a single object
    public float smoothingSpeed = 5f; // Controls how fast the visualizer responds
    private float[] spectrumData = new float[64]; // Raw spectrum data
    private float[] smoothedSpectrumData = new float[64]; // Smoothed spectrum data
    public float visualizerScale = 5f; // Controls how much the bars scale
    public LayerMask audioSourceMask; // Layer mask to filter the audio sources

    // Frequency bias toggle
    public bool prioritizeHighFrequencies = false; // Set this flag to prioritize high frequencies or not

    // Material property settings
    public string materialColorProperty = "_Color"; // Material color property to modify
    public string materialEmissionProperty = "_EmissionColor"; // Emission property to modify
    public float baseEmissionIntensity = 2f; // Base emission intensity multiplier
    public float highFrequencyEmissionBoost = 2f; // Boost for high-frequency emissive intensity

    // Colors for different spectrum ranges
    public Color lowFrequencyColor = Color.blue;   // Low-frequency range color
    public Color midFrequencyColor = Color.green;  // Mid-frequency range color
    public Color highFrequencyColor = Color.red;   // High-frequency range color

    void Update()
    {
        // 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];
                }
            }
        }

        for (int i = 0; i < Visualizer.Length; i++)
        {
            if (i >= spectrumData.Length)
            {
                Debug.LogWarning($"Visualizer index {i} exceeds spectrumData length {spectrumData.Length}. Stopping loop early.");
                break;
            }

            if (Visualizer[i] == null)
            {
                Debug.LogWarning($"Visualizer element at index {i} is null. Skipping this element.");
                continue;
            }

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

            // Apply frequency bias: Only affect low or high frequencies based on the toggle
            float frequencyWeight = 1f;
            if (prioritizeHighFrequencies)
            {
                // For high frequencies, scale down low frequencies to 0
                frequencyWeight = i >= spectrumData.Length / 2 ? 1f : 0f; // High frequencies are in the upper half of spectrum
            }
            else
            {
                // For low frequencies, scale down high frequencies to 0
                frequencyWeight = i < spectrumData.Length / 2 ? 1f : 0f; // Low frequencies are in the lower half of spectrum
            }

            float weightedSpectrum = smoothedSpectrumData[i] * frequencyWeight;

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

            // Update material properties based on spectrum range
            Renderer renderer = Visualizer[i].GetComponent<Renderer>();
            if (renderer != null)
            {
                Material material = renderer.material;

                // Determine the range position
                float rangePosition = (float)i / Visualizer.Length; // Normalize to 0-1
                Color rangeColor;

                if (rangePosition < 0.33f) // Low frequency
                {
                    float lerpValue = rangePosition / 0.33f; // Normalize to 0-1 within range
                    rangeColor = Color.Lerp(lowFrequencyColor, midFrequencyColor, lerpValue);
                }
                else if (rangePosition < 0.66f) // Mid frequency
                {
                    float lerpValue = (rangePosition - 0.33f) / 0.33f; // Normalize to 0-1 within range
                    rangeColor = Color.Lerp(midFrequencyColor, highFrequencyColor, lerpValue);
                }
                else // High frequency
                {
                    float lerpValue = (rangePosition - 0.66f) / 0.34f; // Normalize to 0-1 within range
                    rangeColor = Color.Lerp(highFrequencyColor, Color.white, lerpValue); // Add white for more brightness
                }

                // Adjust intensity using smoothed spectrum data
                float adjustedEmissionIntensity = baseEmissionIntensity;
                if (rangePosition >= 0.66f) // High-frequency boost
                {
                    adjustedEmissionIntensity += highFrequencyEmissionBoost;
                }

                Color finalColor = rangeColor * Mathf.Clamp01(weightedSpectrum * 10f);

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

                // Enable emission (if not already enabled)
                material.EnableKeyword("_EMISSION");
            }
            else
            {
                Debug.LogWarning($"Renderer component missing on Visualizer element at index {i}. Skipping material updates.");
            }
        }
    }
}