// 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 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); } } }