chip-game/Assets/Scripts/SoundManager.cs
2026-08-19 09:18:27 +03:00

273 lines
8.6 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 UnityEngine;
//зависит от ComWrapper, SettingsManager
public class SoundManager : MonoBehaviour
{
public static SoundManager instance;
public AudioSource chipLandSound;
public AudioSource chipDownSound;
public AudioClip down1, down2;
public AudioSource VideoAudio;
public AudioSource music;
public AudioSource wrongSound;
public AudioSource winEffect;
public AudioSource addCoin;
public AudioSource removeCoin;
public AudioSource noMoney;
public AudioSource explosion;
public AudioSource choose;
public AudioSource timer;
public GameObject switchEffectPrefab;
// Кешированные длительности клипов
private float switchEffectDuration;
private float player1LandDuration;
private float effectsVolume;
// Кешированные AudioClips для пула
private AudioClip switchEffectClip;
[SerializeField] AudioClip player1LandClip;
// Пул объектов для звуковых эффектов
private const int AUDIO_POOL_SIZE = 12;
private GameObject[] audioPool;
private int poolIndex = 0;
private float musicVolume = 0.5f;
private float promoVolume = 0.5f;
public void Initialize()
{
if (instance == null)
{
instance = this;
InitializeAudioPool();
}
else
{
Destroy(gameObject);
return;
}
Instantiate(new GameObject()).AddComponent(typeof(VfxPrefab));
switchEffectClip = switchEffectPrefab.GetComponent<AudioSource>().clip;
switchEffectDuration = switchEffectClip.length;
player1LandDuration = player1LandClip.length;
PaymentSystem.onCoinAdded += playAddCoin;
PaymentSystem.onCoinRemoved += playRemoveCoin;
PaymentSystem.OnNotEnoughMoney += playNoMoney;
ApplySettings();
SettingsManager.OnSettingsChanged.AddListener(ApplySettings);
}
private void Start()
{
}
private void InitializeAudioPool()
{
audioPool = new GameObject[AUDIO_POOL_SIZE];
for (int i = 0; i < AUDIO_POOL_SIZE; i++)
{
audioPool[i] = new GameObject("AudioPoolObject");
audioPool[i].AddComponent<AudioSource>();
audioPool[i].SetActive(false);
}
}
private GameObject GetPooledAudioObject()
{
GameObject obj = audioPool[poolIndex];
poolIndex = (poolIndex + 1) % AUDIO_POOL_SIZE;
return obj;
}
public void ApplySettings()
{
print("Применяем настройки звука");
musicVolume = SettingsManager.GetFloat("MusicVolume", 0.5f);
promoVolume = SettingsManager.GetFloat("PromoVolume", 0.5f);
music.volume = musicVolume;
effectsVolume = SettingsManager.GetFloat("SoundsVolume", 0.5f);
// Массив для оптимизации установки громкости
AudioSource[] audioSources = { chipLandSound, chipDownSound, wrongSound, winEffect,
addCoin, removeCoin, noMoney, explosion, choose };
foreach (var audioSource in audioSources)
{
audioSource.volume = effectsVolume;
}
VideoAudio.volume = promoVolume;
}
public void SetMusicVolumeToVideo() => VideoAudio.volume = musicVolume;
public void SetPromoVolumeToVideo() => VideoAudio.volume = promoVolume;
public void playClip(AudioClip clip)
{
if (clip == null)
{
Debug.LogWarning("Не установлен звук");
return;
}
GameObject effect = GetPooledAudioObject();
AudioSource audioSource = effect.GetComponent<AudioSource>();
//AudioClip clipToPlay = GameManager.instance.currentPlayer == CellState.Player1 ? down1 : down2;
AudioClip clipToPlay = clip;
audioSource.clip = clipToPlay;
audioSource.pitch = 1;
audioSource.volume = effectsVolume;
effect.SetActive(true);
audioSource.Play();
// Возвращаем в пул через время клипа
StartCoroutine(ReturnToPool(effect, clipToPlay.length));
}
public void playDropDown()
{
// Используем пул объектов вместо создания новых
GameObject effect = GetPooledAudioObject();
AudioSource audioSource = effect.GetComponent<AudioSource>();
//AudioClip clipToPlay = GameManager.instance.currentPlayer == CellState.Player1 ? down1 : down2;
AudioClip clipToPlay = down2;
audioSource.clip = clipToPlay;
//audioSource.pitch = 1 + Random.Range(0, 2) * 0.6f;
audioSource.pitch = GameManager.instance.currentPlayer == CellState.Player1 ? 1 : 1.3f;
audioSource.volume = effectsVolume;
effect.SetActive(true);
audioSource.Play();
// Возвращаем в пул через время клипа
StartCoroutine(ReturnToPool(effect, clipToPlay.length));
}
public void playChipBounce()
{
// Используем пул объектов вместо Instantiate
GameObject effect = GetPooledAudioObject();
AudioSource audioSource = effect.GetComponent<AudioSource>();
// Выбираем нужный клип и длительность
AudioClip clipToPlay = player1LandClip;
float duration = player1LandDuration;
audioSource.clip = clipToPlay;
audioSource.volume = effectsVolume;
audioSource.pitch = GameManager.instance.currentPlayer == CellState.Player1 ? 0.8f : 0.85f;
effect.SetActive(true);
audioSource.Play();
// Возвращаем в пул через время клипа
StartCoroutine(ReturnToPool(effect, duration));
}
public void playSwitch()
{
// Используем пул объектов вместо Instantiate
GameObject effect = GetPooledAudioObject();
AudioSource audioSource = effect.GetComponent<AudioSource>();
audioSource.clip = switchEffectClip;
audioSource.volume = effectsVolume;
audioSource.pitch = 1f; // Сбрасываем pitch для consistency
effect.SetActive(true);
audioSource.Play();
// Возвращаем в пул через время клипа
StartCoroutine(ReturnToPool(effect, switchEffectDuration));
}
private IEnumerator ReturnToPool(GameObject obj, float delay)
{
yield return new WaitForSeconds(delay);
obj.SetActive(false);
}
Coroutine musicCoroutine;
public void MusicFade(float fadeDuration, float holdDuration, float targetVolumePercent)
{
if (musicCoroutine != null)
{
StopCoroutine(musicCoroutine);
}
//восстанавливаю громкость
float musicVolume = SettingsManager.GetFloat("MusicVolume", 0.5f);
music.volume = musicVolume;
musicCoroutine = StartCoroutine(MusicFadeCoroutine(fadeDuration, holdDuration, targetVolumePercent));
}
IEnumerator MusicFadeCoroutine(float fadeDuration, float holdDuration, float targetVolumePercent)
{
float startVolume = music.volume;
float targetVolume = startVolume * Mathf.Clamp01(targetVolumePercent);
// Fade to target volume
float timer = 0f;
while (timer < fadeDuration)
{
timer += Time.deltaTime;
float progress = timer / fadeDuration;
music.volume = Mathf.Lerp(startVolume, targetVolume, progress);
yield return null;
}
music.volume = targetVolume; // Ensure exact target volume
// Hold at target volume
if (holdDuration > 0f)
yield return new WaitForSeconds(holdDuration);
// Fade back to original volume
timer = 0f;
while (timer < fadeDuration)
{
timer += Time.deltaTime;
float progress = timer / fadeDuration;
music.volume = Mathf.Lerp(targetVolume, startVolume, progress);
yield return null;
}
music.volume = startVolume; // Ensure exact start volume
}
public void playWrong() => wrongSound.Play();
public void playWin() => winEffect.Play();
public void playAddCoin(int newCount) => addCoin.Play();
public void playRemoveCoin(int newCount) => removeCoin.Play();
public void playNoMoney() => noMoney.Play();
public void playExplosion() => explosion.Play();
public void playChoose() => choose.Play();
public void playTimer() => timer.Play();
}