Game.Audio.AudioManager
Assembly: Assembly-CSharp
Namespace: Game.Audio
Type: class
Base: GameSystemBase, IDefaultSerializable, ISerializable, IPreDeserialize, IPreSerialize
Summary:
Manages all game audio systems: UI and in-game sound effects, ambience, radio, menu music, disaster/lighting sounds and audio mixing. Handles pooling of Unity AudioSource instances (AudioSourcePool), audio clip memory budgeting, creation and updating of 3D audio sources, fading, doppler/velocity audio behavior, and serialization of persistent radio settings. Integrates with the game's ECS systems (PrefabSystem, EffectControlSystem, SimulationSystem, TimeSystem) to spawn, update and remove audio tied to entities and effects. Designed to run on the main thread while accepting job-system source update submissions via a NativeQueue/JobHandle pattern.
Fields
-
private List<AudioInfo> m_AudioInfos
Holds active audio instances currently playing (audio source + source info, fade status, velocity, etc.). -
private AudioMixer m_Mixer
Reference to the master AudioMixer loaded from resources ("Audio/MasterMixer"). Used to set group volumes and manage fades. -
private AudioMixerGroup m_AmbientGroup, m_InGameGroup, m_RadioGroup, m_UIGroup, m_MenuGroup, m_WorldGroup, m_ServiceBuildingGroup, m_AudioGroupGroup, m_DisasterGroup
Cached AudioMixerGroup references for routing AudioSources based on MixerGroup assigned in SFX settings. -
private AudioLoop m_MainMenuMusic
Manages the currently playing menu music loop (used by PlayMenuMusic/StopMenuMusic). -
private AudioSource m_UIAudioSource, m_UIHtmlAudioSource
Dedicated AudioSource for UI one-shots and an HTML UI audio source used for web/html UI audio playback (created on demand). -
private AudioListener m_AudioListener
Singleton AudioListener used to place the listener in world space; updated every frame. -
private NativeQueue<SourceUpdateInfo> m_SourceUpdateQueue
Queue used by other systems/jobs to submit SourceUpdateInfo events to the AudioManager (Add/Remove/Temp/Snap/WrongPrefab). Written to from jobs through m_SourceUpdateData. -
private SourceUpdateData m_SourceUpdateData
Wrapper object exposing a ParallelWriter to jobs for enqueuing SourceUpdateInfo. -
private JobHandle m_SourceUpdateWriter
Accumulated job dependencies for the writer; completed before main-thread dequeue. -
private NativeParallelHashMap<SourceInfo, int> m_CurrentEffects
Maps active SourceInfo -> index in m_AudioInfos for quick lookup and management. -
private SimulationSystem m_SimulationSystem
Reference to the SimulationSystem for frame/speed information and frame index. -
private PrefabSystem m_PrefabSystem
Reference to the PrefabSystem to resolve effect/prefab data for audio. -
private GameScreenUISystem m_GameScreenUISystem
Used to detect menu activation to fade audio appropriately. -
private EffectControlSystem m_EffectControlSystem
Used to obtain enabled effect data (intensity/position) for audio updates. -
private RandomSeed m_RandomSeed
Utility used to produce deterministic randomization for selecting audio variations. -
private float m_DeltaTime
Frame delta time cached each OnUpdate to compute fades/velocities. -
private FadeStatus m_AudioFadeStatus
Tracks global fade state (None/FadeIn/FadeOut) used for pausing/unpausing game/menu transitions. -
private List<SFX> m_Clips
Indexed registry of SFX objects loaded from prefabs; used to reference clip data by id. -
private List<CameraAmbientAudioInfo> m_CameraAmbientSources
Ambient audio sources attached to the camera (global ambience layers). -
private List<AudioSource> m_TempAudioSources
AudioSources created for short-lived (temp) one-shot events like lightning; cleaned up when finished. -
private Game.Audio.Radio.Radio m_Radio
Manages in-game radio stations, channels and playback. -
private SynchronizationContext m_MainThreadContext
Main thread sync context used by ResetAudioOnMainThread and similar operations that must run on Unity main thread. -
private static readonly ILog log
Logger instance ("Audio") for warnings and debug output. -
public static AudioManager instance { get; private set; }
Singleton reference to the AudioManager created in OnCreate.
(There are many other private fields and nested types; the above are the most relevant for modders integrating with or extending audio behavior.)
Properties
-
public AudioSource UIHtmlAudioSource { get; }
Creates (on demand) and returns a dedicated UI HTML AudioSource routed to the UI group with ignoreListenerPause = true. Created with DontDestroyOnLoad. -
public Game.Audio.Radio.Radio radio { get; }
Accessor for the Radio subsystem; use to query radio state, channels and control station playback. -
public Entity followed { private get; set; }
Entity currently being "followed" by the camera; used to boost or pin audio sources (e.g., when following a vehicle). -
public float masterVolume { get; set; }
Top-level master volume (uses AudioMixer parameter "MasterVolume" internally). Setting clamps/log-converts to dB. -
public float radioVolume { get; set; }
Radio mixer volume (AudioMixer parameter "RadioVolume"). -
public float uiVolume { get; set; }
UI mixer volume. -
public float menuVolume { get; set; }
Menu music volume. -
public float ingameVolume { get; set; }
In-game SFX group volume. -
public float ambienceVolume { get; set; }
Ambience/mood audio volume. -
public float disastersVolume { get; set; }
Volume for disaster-related audio (e.g., storms, lightning). -
public float worldVolume { get; set; }
General world sound volume. -
public float audioGroupsVolume { get; set; }
Volume for grouped audio (e.g., custom audio groups). -
public float serviceBuildingsVolume { get; set; }
Volume for service building audio.
(Each volume property reads/writes float values to the mixer using logarithmic dB conversion; SetVolume has logic to ignore changes in certain UI/menu states to preserve fading behavior.)
Constructors
-
public AudioManager()
Default constructor (empty). Initialization occurs during OnCreate override. -
protected override void OnCreate()
Initializes singleton instance, creates AudioListener, loads master mixer/groups, creates radio subsystem, allocates NativeQueue and NativeParallelHashMap, resolves world systems (TimeSystem, SimulationSystem, PrefabSystem, EffectControlSystem), prepares queries and data structures. Also resets AudioSourcePool.
Methods
-
protected override void OnDestroy()
Cleans up AudioLoop, disables radio, disposes native containers, completes any outstanding writer job handle, clears temp AudioSources and camera ambient sources, and calls base.OnDestroy. -
public void Reset()
Releases all pooled/active AudioSources, clears m_CurrentEffects and m_AudioInfos and camera ambient sources. Does not block; intended for main-thread usage. -
public async Task ResetAudioOnMainThread()
Schedules Reset() to run on the main Unity thread via m_MainThreadContext and awaits completion. Useful if calling from a background thread. -
public void SetGlobalAudioSettings()
Creates ambient audio camera sources from AmbientAudioSettingsData singleton and effect prefabs. Adds AudioSources from pool and configures positions, distances and volumes. -
public void UpdateGlobalAudioSources(UnityEngine.Transform cameraTransform)
Updates positions of camera-anchored ambient audio sources each frame. -
public SourceUpdateData GetSourceUpdateData(out JobHandle deps)
Returns the SourceUpdateData writer and the current writer JobHandle dependencies so job authors can know dependencies. -
public void AddSourceUpdateWriter(JobHandle jobHandle)
Combine given jobHandle into m_SourceUpdateWriter (accumulates dependencies that must be completed before dequeuing updates). -
public int RegisterSFX(SFX sfx)
Registers an SFX into m_Clips list returning an index. Avoids duplicates by returning existing index if already registered. -
public bool PlayUISoundIfNotPlaying(Entity clipEntity, float volume = 1f)
Plays a UI sound described by an entity (supports AudioRandomizeData or AudioEffectData) if no UI audio is currently playing; returns whether it was played. -
public void PlayUISound(Entity clipEntity, float volume = 1f)
Plays a UI sound (one-shot) using the dedicated UI AudioSource. Supports randomized audio buffers. -
public bool PlayUISoundIfNotPlaying(AudioClip clipEntity, float volume = 1f)
Plays a raw AudioClip as UI one-shot if the UI AudioSource is idle. -
public void PlayUISound(AudioClip clip, float volume = 1f)
Plays a raw AudioClip on the UI AudioSource (creates it if needed). Logs a warning when clip is null. -
public AudioSource PlayExclusiveUISound(Entity clipEntity)
Creates and returns an exclusive pooled AudioSource for UI audio (looping/permanent until explicitly released). Caller should call StopExclusiveUISound to release. -
public void StopExclusiveUISound(AudioSource audioSource)
Releases an exclusive UI AudioSource back to the pool. -
public async Task PlayMenuMusic(string tag)
Finds a random AudioAsset matching tag, creates an AudioLoop, starts playback (awaits start), and disables radio. Increments internal play counter. -
private void UpdateMenuMusic()
Tick/update method for the menu music AudioLoop (called each OnUpdate). -
public void StopMenuMusic()
Fades out current menu music (if any). -
public void PlayLightningSFX(float3 targetPos)
Plays a lightning SFX at targetPos taking into account sound travel delay (distance / lightning sound speed) from WeatherAudioData. Uses GetRandomizeAudio to pick variant or the direct configured clip. Uses pooled AudioSource and PlayDelayed to enforce delay. -
public void Serialize<TWriter>(TWriter writer) where TWriter : IWriter
Writes last radio channel name and skip-ads setting to the save writer, if radio info exists. -
public void Deserialize<TReader>(TReader reader) where TReader : IReader
Reads radio channel and skip-ads flags from the reader when available (checks reader.context.version). -
public void SetDefaults(Context context)
Resets radio save fields to defaults (empty/false). -
public void PreDeserialize(Context context)
Called before deserialization; resets radio save fields. -
public void PreSerialize(Context context)
Called before serialization; resets radio save fields. -
protected override void OnGamePreload(Purpose purpose, GameMode mode)
Called during preload: disables radio and resets audio state. -
protected override void OnGameLoaded(Context serializationContext)
Restores radio settings and reloads radio when loading or starting a new game. -
protected override void OnGameLoadingComplete(Purpose purpose, GameMode mode)
Stops menu music if appropriate when game loading completes. -
protected override void OnUpdate()
Main update loop: completes queued writer job handle, processes source updates (dequeues SourceUpdateInfo entries and handles Add/Remove/Temp/Snap/WrongPrefab), updates UI/menu fades, updates radio, manages ambient sources and temp sources, updates / syncs active audio sources by querying ECS data, applies fades and doppler/velocity effects, and removes finished sources. This method is the core of audio lifecycle logic. -
private float GetFadedVolume(FadeStatus status, float2 sfxFades, float currentVolume, float targetVolume)
Computes faded volume for fade-in/fade-out given configured fade durations and delta time. -
private void Fadeout(SourceInfo sourceInfo, int index)
Marks an active audio instance to begin fade-out. -
private void RemoveAudio(SourceInfo sourceInfo, int index)
Releases an audio instance, removes it from m_AudioInfos and updates m_CurrentEffects indexes. -
private void SyncAudioSources()
Validates and synchronizes m_AudioInfos with game/entity state, removing stopped or invalid audio and updating each source's transform/volume/velocity using ECS lookups and effect intensity data. -
private void UpdateTempAudioSources()
Releases temp AudioSources that finished playing and cleans up invalid GameObjects. -
public static float3 GetClosestSourcePosition(float3 targetPosition, Game.Objects.Transform sourceTransform, float3 sourceOffset, float3 sourceSize)
Utility to clamp a target position to a box volume defined by sourceOffset/sourceSize relative to sourceTransform (used for source size handling). -
private void UpdateAudioSourceByVelocity(AudioSource audioSource, float velocity, VehicleAudioEffectData vehicleData, FadeStatus status)
Adjusts pitch and volume of vehicle audio by velocity normalized to configured limits and speed/volume curves. Applies fade-out caps. -
private bool UpdateAudioSource(AudioSource audioSource, SFX sfx, Game.Objects.Transform transform, float intensity, bool disableDoppler, int i = -1, FadeStatus status = FadeStatus.None, SourceInfo sourceInfo = default(SourceInfo))
Updates position, doppler, volume (with fading) and returns whether source should remain. If fading to zero it will remove the audio via RemoveAudio. -
private AudioMixerGroup GetAudioMixerGroup(MixerGroup group)
Maps MixerGroup enum to the cached AudioMixerGroup references. -
private void SetAudioSourceData(AudioSource audioSource, SFX sfx, float volume)
Applies SFX configuration to an AudioSource (pitch, volume, clip, loop, rolloff, min/max distance, custom curves, random start time, ignore listener pause, priority and output group). -
public bool GetRandomizeAudio(Entity sfxEntity, out SFX sfx)
If sfxEntity has AudioRandomizeData buffer, picks a random SFX variant and returns it; otherwise returns false. -
private void __AssignQueries(ref SystemState state)
Compiler-assigned method used to setup entity queries (internal).
(There are additional private helper methods and nested types; these are the most useful for modding/integration.)
Usage Example
// Example: playing a UI sound and starting menu music from a mod script.
// Assumes AudioManager.instance is available (created during game/system startup).
// Play a one-shot UI sound from an AudioEffectData entity:
Entity uiClipEntity = /* obtain entity that has AudioEffectData or AudioRandomizeData */;
AudioManager.instance?.PlayUISoundIfNotPlaying(uiClipEntity, 0.8f);
// Play raw AudioClip (one-shot)
AudioClip clip = /* your AudioClip reference */;
AudioManager.instance?.PlayUISound(clip, 0.6f);
// Start menu music asynchronously (tagged audio assets)
await AudioManager.instance?.PlayMenuMusic("menu_theme");
// Register a custom SFX (if creating SFX programmatically)
SFX mySfx = /* new SFX configured from your prefab or code */;
int sfxIndex = AudioManager.instance?.RegisterSFX(mySfx) ?? -1;
Notes: - Many AudioManager methods and data structures assume main-thread access (Unity API calls). Use ResetAudioOnMainThread when invoking Reset from background tasks. - For adding/removing in-game audio tied to entities, other systems typically enqueue SourceUpdateInfo via the provided SourceUpdateData writer; modders integrating at the job layer should use GetSourceUpdateData and AddSourceUpdateWriter to properly chain dependencies. - To route custom AudioSources into the game's mixer groups, use the MixerGroup enum and SetAudioSourceData helper to get consistent settings.