sea-battle/Assets/Scripts/SoundManager.cs

211 lines
6.3 KiB
C#

// Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
// SoundManager
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SoundManager : MonoBehaviour
{
public static SoundManager Instance;
[Header("Player 1 AudioSources")]
public AudioSource player1VoiceSource;
public AudioSource player1EffectsSource;
[Header("Player 2 AudioSources")]
public AudioSource player2VoiceSource;
public AudioSource player2EffectsSource;
[Header("Фоновая музыка")]
public AudioSource musicSource;
[Header("Настройки аудио выходов")]
[Tooltip("Включить раздельные аудио выходы для игроков (требует Unity 2022.2+)")]
public bool useSeparateAudioOutputs = false;
[Tooltip("Индекс аудио устройства для игрока 1 (0 = default)")]
public int player1AudioDevice = 0;
[Tooltip("Индекс аудио устройства для игрока 2 (1 = второе устройство)")]
public int player2AudioDevice = 1;
public AudioClip[] backgroundMusic;
private int currentTrackIndex = -1;
[Header("Общие эффекты")]
public AudioClip[] shootSounds;
public AudioClip[] explosionSounds;
public AudioClip[] missSounds;
[Header("Профили звуков")]
public List<SoundProfile> soundProfiles;
private void Awake()
{
if (Instance == null)
{
Instance = this;
}
else
{
UnityEngine.Object.Destroy(base.gameObject);
}
UnityEngine.Object.DontDestroyOnLoad(base.gameObject);
}
private void Start()
{
ApplyAudioSettings();
if (backgroundMusic.Length != 0 && musicSource != null)
{
StartCoroutine(MusicLoop());
}
}
private void OnEnable()
{
if (SettingsManager.instance != null)
{
SettingsManager.instance.OnSettingsChanged.AddListener(ApplyAudioSettings);
}
}
private void OnDisable()
{
if (SettingsManager.instance != null)
{
SettingsManager.instance.OnSettingsChanged.RemoveListener(ApplyAudioSettings);
}
}
private void ApplyAudioSettings()
{
float volume = (float)Convert.ToInt32(SettingsManager.instance.GetSettingValue("Громкость музыки")) / 10f;
float volume2 = (float)Convert.ToInt32(SettingsManager.instance.GetSettingValue("Громкость эффектов")) / 10f;
float volume3 = (float)Convert.ToInt32(SettingsManager.instance.GetSettingValue("Громкость голоса")) / 10f;
musicSource.volume = volume;
player1VoiceSource.volume = volume2;
player1EffectsSource.volume = volume3;
player2VoiceSource.volume = volume2;
player2EffectsSource.volume = volume3;
}
private IEnumerator MusicLoop()
{
while (true)
{
PlayNextTrack();
yield return new WaitForSeconds(musicSource.clip.length);
}
}
private void PlayNextTrack()
{
if (backgroundMusic.Length != 0)
{
int num = UnityEngine.Random.Range(0, backgroundMusic.Length);
if (num == currentTrackIndex && backgroundMusic.Length > 1)
{
num = (num + 1) % backgroundMusic.Length;
}
currentTrackIndex = num;
musicSource.clip = backgroundMusic[currentTrackIndex];
musicSource.Play();
}
}
public void PlayVoice(int playerId, AudioClip clip)
{
if (clip == null) return;
AudioSource source = GetVoiceSource(playerId);
// Прерываем предыдущую фразу, если нужно (для голоса это обычно желательно)
source.Stop();
ApplyPlayerPan(source, playerId);
source.PlayOneShot(clip);
}
// Устанавливает 2D режим и панораму для маршрутизации в VoiceMeeter (player1 -> left, player2 -> right)
private void ApplyPlayerPan(AudioSource src, int playerId)
{
if (src == null) return;
src.spatialBlend = 0f; // 2D
src.panStereo = (playerId == 1) ? -1f : 1f;
}
private AudioSource GetVoiceSource(int playerId)
{
if (playerId != 1)
{
return player2VoiceSource;
}
return player1VoiceSource;
}
private AudioSource GetEffectsSource(int playerId)
{
if (playerId != 1)
{
return player2EffectsSource;
}
return player1EffectsSource;
}
private void StopAllPlayerSounds(int playerId)
{
GetVoiceSource(playerId).Stop();
GetEffectsSource(playerId).Stop();
}
// Публичный метод чтобы прекратить только голосовой канал указанного игрока
public void StopVoice(int playerId)
{
var src = GetVoiceSource(playerId);
if (src != null)
src.Stop();
}
public void PlayShoot(int playerId)
{
if (shootSounds.Length != 0)
{
AudioClip clip = shootSounds[UnityEngine.Random.Range(0, shootSounds.Length)];
AudioSource src = GetEffectsSource(playerId);
ApplyPlayerPan(src, playerId);
GetEffectsSource(playerId).PlayOneShot(clip, 0.8f);
}
}
public void PlayExplosion(int playerId)
{
if (explosionSounds.Length != 0)
{
AudioClip clip = explosionSounds[UnityEngine.Random.Range(0, explosionSounds.Length)];
AudioSource src = GetEffectsSource(playerId);
ApplyPlayerPan(src, playerId);
GetEffectsSource(playerId).PlayOneShot(clip, 3.0f);
}
}
public void PlayMiss(int playerId)
{
if (missSounds.Length != 0)
{
AudioClip clip = missSounds[UnityEngine.Random.Range(0, missSounds.Length)];
AudioSource src = GetEffectsSource(playerId);
ApplyPlayerPan(src, playerId);
GetEffectsSource(playerId).PlayOneShot(clip, 0.5f);
}
}
}