Аудиосистема
Аудиосистема OpenMon — это пул-ориентированный 2D-движок на базе Unity AudioMixer. Она разделена на два слоя: Foundation (OpenMon.Foundation.Audio) предоставляет общий движок воспроизведения, а Core (OpenMon.MCE.Audio) добавляет игровые настройки громкости и сохранения.

Три независимые шины — общая, музыка и эффекты — причём общая умножает две другие, а не заменяет их; поэтому отключение музыки не заглушает удар в бою.
Архитектура
| Класс | Слой | Назначение |
|---|---|---|
AudioManager | Foundation | Синглтон с пулом AudioSource; воспроизводит/останавливает/затухает клипы |
AudioLibrary | Foundation | ScriptableObject, регистрирующий каждый AudioClip с его AudioMixerGroup |
AudioReference | Foundation | Лёгкий сериализуемый struct, ссылающийся на клип по имени |
AudioSettingsManager | Core | Читает/записывает настройки громкости и применяет их к микшеру |
AudioConfiguration | Core | Сериализуемый класс данных с уровнями Master, Music и FX |
AudioInstaller | Foundation | ScriptableObjectInstaller Zenject, биндящий IAudioManager и IAudioLibrary |
AudioSettingsInstaller | Core | Installer Zenject, биндящий AudioSettingsManager и AudioMixer |
AudioManager
AudioManager — синглтон (Singleton<AudioManager>), реализующий IAudioManager. Он управляет динамическим пулом компонентов AudioSource на своём GameObject. При запросе воспроизведения менеджер либо переиспользует свободный источник из пула, либо создаёт новый.
Воспроизведение
// Простой one-shot
AudioManager.Instance.PlayAudio(myAudioReference);
// Зацикленный BGM с плавным появлением
AudioManager.Instance.PlayAudio(bgmReference, loop: true, fadeTime: 1.5f);
// Произвольные pitch и громкость
AudioManager.Instance.PlayAudio(sfxReference, pitch: 1.2f, volume: 0.8f);
Каждый вызов разрешает AudioReference через AudioLibrary, получает клип и его mixer group, затем назначает их пулированному AudioSource. Если fadeTime > 0, менеджер запускает корутину, которая интерполирует громкость от 0 до целевой.
Остановка
// Мгновенная остановка
AudioManager.Instance.StopAudio(bgmReference);
// Затухание за 2 секунды, затем остановка
AudioManager.Instance.StopAudio(bgmReference, fadeTime: 2f);
// Аварийная остановка всего (например, прерывание битвы)
AudioManager.Instance.StopAllAudios();
Глобальное отключение / восстановление звука
Эти корутины работают с параметром MasterVolume AudioMixer, позволяя отключить весь звук без остановки отдельных источников. Полезно для переходов между сценами и экранов паузы.
StartCoroutine(AudioManager.Instance.MuteAllAudios(fadeTime: 1f));
StartCoroutine(AudioManager.Instance.UnmuteAllAudios(fadeTime: 1f));
Жизненный цикл пула
Пул самоуправляемый. Каждый кадр CheckAudioSourceAvailability() сканирует все источники. Любой источник, закончивший воспроизведение, помечается как доступный, и его ссылка на клип очищается. Если ни один другой источник не использует этот клип, библиотека уведомляется через FreeAudioAsset() для возможной выгруз ки.
AudioLibrary
AudioLibrary — это ScriptableObject (создаётся через OpenMon > Audio > Audio Library), служащий центральным реестром аудио. Он хранит SerializableDictionary<AudioClip, AudioMixerGroup>, сопоставляющий каждый клип с его mixer group (BGM, SFX, ME и т.д.).
AudioLibrary (ScriptableObject)
+-- "battle_bgm_01" -> BGM MixerGroup
+-- "ui_confirm" -> SFX MixerGroup
+-- "level_up_jingle" -> ME MixerGroup
+-- "cry_001" -> SFX MixerGroup
...
В редакторе библиотека кэширует плоские списки имён клипов, ссылок и mixer groups для быстрого поиска O(n) по имени. Команда Cache Audio References из контекстного меню перестраивает эти кэши после добавления или удаления клипов.
Утилита редактора
Конвейер импортёра может автоматически регистрировать клипы:
audioLibrary.AddAudioIfItsNotIn(clip, mixerGroup);
AudioReference
AudioReference — простой сериализуемый struct с единственным полем string Audio. Оно соответствует имени клипа, зарегистрированного в AudioLibrary. Это отделяет сериализованные данные сцен/префабов от прямых ссылок на клипы, позволяя реорганизовывать аудиофайлы без поломки ссылок в инспекторе.
[Serializable]
public struct AudioReference
{
public string Audio; // Должно совпадать с именем в AudioLibrary
}
Используйте поля AudioReference в ваших MonoBehaviour, ScriptableObject или узлах CommandGraph для ссылки на аудио по имени.
AudioSettingsManager
AudioSettingsManager — игровой контроллер громкости. Он читает AudioConfiguration из системы персистентной конфигурации и применяет три уровня к AudioMixer:
- MasterVolume — общая громкость игры
- MusicVolume — громкость группы BGM
- FXVolume — громкость звуковых эффектов и джинглов
Преобразование громкости
Человеческое восприятие громкости логарифмично. Система использует AudioUtils для конвертации между линейным диапазоном 0–1 слайдеров и шкалой децибел AudioMixer:
float db = AudioUtils.LinearVolumeToLogarithmicVolume(0.5f); // ~ -6 dB
float linear = AudioUtils.LogarithmicVolumeToLinearVolume(-6f); // ~ 0.5
Сохранение настроек
Предпочтения громкости сохраняются через систему IConfigurationManager. Когда игрок двигает слайдер в экране опций, UI вызывает:
audioSettingsManager.SetAudioConfiguration(new AudioConfiguration
{
MasterVolume = masterSlider.value,
MusicVolume = musicSlider.value,
FXVolume = fxSlider.value
});
Это записывает конфигурацию на диск и немедленно применяет новые значения к микшеру. При запуске AudioSettingsManager.Construct() вызывается через внедрение Zenject и применяет сохранённые настройки в следующем кадре.
Настройка DI
Оба установщика — ScriptableObjectInstaller Zenject, добавляемые в SceneContext сцены:
- AudioInstaller — биндит
IAudioManager(черезAudioManager.Instance),IAudioLibrary(черезAudioLibraryasset) иAudioMixer. - AudioSettingsInstaller — биндит
AudioSettingsManagerкак ленивый синглтон и инжектируетAudioMixer.
SceneContext
+-- AudioInstaller (ссылка на AudioLibrary + AudioMixer)
+-- AudioSettingsInstaller (ссылка на AudioMixer)
Использование в CommandGraph
Воспроизведение аудио можно запускать из скриптов событий NPC (CommandGraph). В категории Sounds есть узлы: PlayMusic (трек как музыка мира поверх собственной музыки карты), StopMusic (плавно её затухает), SaveMusic и RestoreSceneMusic (со храняют трек после сражения или возвращают музыку самой карты), PlaySound, PlayMonsterCry и WaitForAudio (удерживает граф, пока не закончится джингл). Узлы ссылаются на клипы через поля AudioReference, которые разрешаются через AudioLibrary во время выполнения. Чтобы заполнить библиотеку клипами, которые уже есть в проекте, используйте Tools > MCE > Audio > Populate Audio Library.
Сводка
| Чтобы... | Используйте... |
|---|---|
| Воспроизвести звуковой эффект | AudioManager.Instance.PlayAudio(ref) |
| Зациклить фоновую музыку | AudioManager.Instance.PlayAudio(ref, loop: true) |
| Сделать кроссфейд к новому BGM | Остановить старый через fadeTime, запустить новый через fadeTime |
| Отключить звук при загрузке сцены | MuteAllAudios(fadeTime) / UnmuteAllAudios(fadeTime) |
| Зарегистрировать новый клип | Добавить в asset AudioLibrary и назначить mixer group |
| Настроить громкость игрока | AudioSettingsManager.SetAudioConfiguration(config) |
| Конвертировать слайдер в дБ | AudioUtils.LinearVolumeToLogarithmicVolume(value) |