Перейти к основному содержимому

Аудиосистема

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

Раздел звука на экране настроек

Три независимые шины — общая, музыка и эффекты — причём общая умножает две другие, а не заменяет их; поэтому отключение музыки не заглушает удар в бою.

Архитектура​

КлассСлойНазначение
AudioManagerFoundationСинглтон с пулом AudioSource; воспроизводит/останавливает/затухает клипы
AudioLibraryFoundationScriptableObject, регистрирующий каждый AudioClip с его AudioMixerGroup
AudioReferenceFoundationЛёгкий сериализуемый struct, ссылающийся на клип по имени
AudioSettingsManagerCoreЧитает/записывает настройки громкости и применяет их к микшеру
AudioConfigurationCoreСериализуемый класс данных с уровнями Master, Music и FX
AudioInstallerFoundationScriptableObjectInstaller Zenject, биндящий IAudioManager и IAudioLibrary
AudioSettingsInstallerCoreInstaller 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 сцены:

  1. AudioInstaller — биндит IAudioManager (через AudioManager.Instance), IAudioLibrary (через AudioLibrary asset) и AudioMixer.
  2. 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)