279 lines
8.9 KiB
C#
279 lines
8.9 KiB
C#
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;
|
||
public GameObject Player1Land, Player2Land;
|
||
|
||
// Кешированные длительности клипов
|
||
private float switchEffectDuration;
|
||
private float player1LandDuration;
|
||
private float player2LandDuration;
|
||
private float effectsVolume;
|
||
|
||
// Кешированные AudioClips для пула
|
||
private AudioClip switchEffectClip;
|
||
private AudioClip player1LandClip;
|
||
private AudioClip player2LandClip;
|
||
|
||
// Пул объектов для звуковых эффектов
|
||
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);
|
||
}
|
||
|
||
|
||
try//todo: переделать этот бред ебаный
|
||
{
|
||
switchEffectClip = switchEffectPrefab.GetComponent<AudioSource>().clip;
|
||
switchEffectDuration = switchEffectClip.length;
|
||
|
||
player1LandClip = Player1Land.GetComponent<AudioSource>().clip;
|
||
player1LandDuration = player1LandClip.length;
|
||
|
||
player2LandClip = Player2Land.GetComponent<AudioSource>().clip;
|
||
player2LandDuration = player2LandClip.length;
|
||
|
||
PaymentSystem.onCoinAdded += playAddCoin;
|
||
PaymentSystem.onCoinRemoved += playRemoveCoin;
|
||
PaymentSystem.OnNotEnoughMoney += playNoMoney;
|
||
|
||
ApplySettings();
|
||
SettingsManager.OnSettingsChanged += ApplySettings;
|
||
|
||
}
|
||
catch { }
|
||
}
|
||
|
||
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(SettingKey.MUSIC_VOLUME);
|
||
promoVolume = SettingsManager.GetFloat(SettingKey.PROMO_VOLUME);
|
||
|
||
music.volume = musicVolume;
|
||
|
||
effectsVolume = SettingsManager.GetFloat(SettingKey.SOUNDS_VOLUME);
|
||
|
||
// Массив для оптимизации установки громкости
|
||
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(SettingKey.MUSIC_VOLUME);
|
||
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();
|
||
}
|