unity-audio-10a023 — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited unity-audio-10a023 (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
Unity's audio system provides full 3D spatial sound, real-time mixing and mastering, hierarchies of mixers, snapshots, and predefined effects. The core architecture follows a source-listener model:
Sounds originate from AudioSources attached to objects and are picked up by the AudioListener. Unity calculates a source's distance and position from the listener to determine volume, panning, and 3D effects. The system also models the Doppler Effect using the relative speed of the source and listener objects.
| Format | Type |
|---|---|
.aif, .wav | Uncompressed |
.mp3, .ogg | Compressed |
.xm, .mod, .it, .s3m | Tracker modules |
Unity supports mono, stereo, and multichannel audio assets (up to eight channels).
The AudioSource component plays an AudioClip in your scene and provides options to customize playback behavior. Key properties:
| Property | Description | Default |
|---|---|---|
clip | The AudioClip to play | None |
volume | Playback volume (0.0 to 1.0) | 1.0 |
pitch | Playback speed/pitch multiplier | 1.0 |
loop | Whether the clip loops on completion | false |
playOnAwake | Auto-play when the GameObject activates | true |
spatialBlend | 2D (0.0) to 3D (1.0) blend | 0.0 |
priority | Source priority (0 = highest, 256 = lowest) | 128 |
mute | Mutes the source without stopping playback | false |
outputAudioMixerGroup | Target mixer group for routing | None |
| Property | Description |
|---|---|
dopplerLevel | Doppler effect intensity scale |
spread | Spread angle in degrees for 3D stereo/multichannel |
rolloffMode | How volume attenuates over distance (Logarithmic, Linear, Custom) |
minDistance | Distance within which volume is at maximum |
maxDistance | Distance beyond which sound is inaudible or stops attenuating |
panStereo | Stereo panning position (-1 left to 1 right) |
reverbZoneMix | Mix level into global reverb |
The AudioListener acts as a microphone-like device that receives input from AudioSources in the scene and outputs through speakers. Critical rules:
Static properties available via script:
AudioListener.volume -- Master volume (0.0 to 1.0)AudioListener.pause -- Pauses/unpauses the entire audio system| Load Type | Behavior | Best For |
|---|---|---|
| Decompress On Load | Decompresses immediately on load; uses ~10x memory for Vorbis, ~3.5x for ADPCM | Small, frequently-used sound effects |
| Compressed In Memory | Keeps compressed in memory, decompresses during playback; slight CPU overhead | Medium sounds where decompress-on-load exceeds memory budget |
| Streaming | Decodes on the fly from disk; uses ~200KB buffer per clip | Long audio like music or ambient tracks |
| Format | Ratio | Best For |
|---|---|---|
| PCM | 1:1 (uncompressed) | Very short effects requiring zero CPU decode cost |
| ADPCM | 3.5:1 | Noise-heavy sounds (footsteps, impacts, weapons) |
| Vorbis/MP3 | Variable (quality slider) | Music and medium-length effects |
| Setting | Description |
|---|---|
| Force To Mono | Mixes multi-channel audio down to a mono track before packing |
| Normalize | Normalizes audio during mono conversion |
| Load In Background | Loads the clip asynchronously to avoid blocking the main thread |
| Ambisonic | Marks the file as containing Ambisonic-encoded soundfields (for XR/360) |
| Preload Audio Data | Preloads clip data when the scene finishes loading (default: enabled) |
| Quality | Compression quality slider for Vorbis/MP3 formats |
| Sample Rate Setting | Preserve, Optimize (auto-adjust), or Override (manual reduction) |
The Audio Mixer provides mixing, effects processing, and mastering for audio output. Every Audio Mixer asset contains a Master Group by default.
Master/SFX/Weapons)SetFloat/GetFloatNote: The Web platform only partially supports Audio Mixers.
using UnityEngine;
using UnityEngine.Audio;
public class MixerController : MonoBehaviour
{
[SerializeField] private AudioMixer mixer;
// Set exposed parameter (must be exposed in the Mixer Inspector)
public void SetVolume(float linear)
{
float dB = Mathf.Log10(Mathf.Max(linear, 0.0001f)) * 20f;
mixer.SetFloat("MasterVolume", dB);
}
// Read exposed parameter (convert dB back to linear)
public float GetVolume()
{
if (mixer.GetFloat("MasterVolume", out float dB))
return Mathf.Pow(10f, dB / 20f);
return 1f;
}
// Reset parameter to snapshot-defined value
public void ResetVolume() => mixer.ClearFloat("MasterVolume");
// Transition to a named snapshot
public void GoToSnapshot(string name, float time)
{
var snap = mixer.FindSnapshot(name);
if (snap != null) snap.TransitionTo(time);
}
// Blend multiple snapshots with weights
public void BlendSnapshots(AudioMixerSnapshot[] snaps, float[] weights, float time)
=> mixer.TransitionToSnapshots(snaps, weights, time);
}Set spatialBlend to 1.0 for full 3D positioning. Unity's built-in panning regulates left/right ear contributions based on distance and angle from the listener.
For advanced 3D audio, Unity supports spatialization plugins with HRTF filtering. Setup: (1) Edit > Project Settings > Audio -- select the spatializer plugin, (2) enable Spatialize on each AudioSource, (3) optionally set spatializePostEffects. Performance tip: spatialize only nearby sounds; use traditional panning on distant ones.
using UnityEngine;
public class SpatialAudioSetup : MonoBehaviour
{
[SerializeField] private AudioSource audioSource;
void Start()
{
// Configure for 3D spatial audio
audioSource.spatialBlend = 1.0f; // Full 3D
audioSource.rolloffMode = AudioRolloffMode.Logarithmic;
audioSource.minDistance = 1f;
audioSource.maxDistance = 50f;
audioSource.dopplerLevel = 1.0f;
audioSource.spread = 0f; // Point source
// Enable spatialization plugin (if configured in Project Settings)
audioSource.spatialize = true;
}
}using UnityEngine;
public class SoundEffectPlayer : MonoBehaviour
{
[SerializeField] private AudioSource audioSource;
[SerializeField] private AudioClip shootClip;
[SerializeField] private AudioClip reloadClip;
// Play the assigned clip
public void PlayShoot()
{
audioSource.Play();
}
// PlayOneShot: plays a clip without interrupting the current one
// Supports overlapping sounds and per-call volume scaling
public void PlayReload(float volumeScale = 1.0f)
{
audioSource.PlayOneShot(reloadClip, volumeScale);
}
// Play a clip at a world position (creates a temporary AudioSource)
public void PlayExplosionAt(Vector3 position)
{
AudioSource.PlayClipAtPoint(shootClip, position, 1.0f);
}
// Play with a delay (in seconds)
public void PlayDelayed()
{
audioSource.PlayDelayed(0.5f);
}
// Scheduled playback on DSP timeline (sample-accurate)
public void PlayScheduled()
{
double startTime = AudioSettings.dspTime + 1.0;
audioSource.PlayScheduled(startTime);
}
}using UnityEngine;
using System.Collections.Generic;
public class AudioPool : MonoBehaviour
{
[SerializeField] private int poolSize = 10;
private List<AudioSource> pool = new List<AudioSource>();
void Awake()
{
for (int i = 0; i < poolSize; i++)
{
var obj = new GameObject($"PooledAudio_{i}");
obj.transform.SetParent(transform);
var src = obj.AddComponent<AudioSource>();
src.playOnAwake = false;
pool.Add(src);
}
}
public AudioSource Play(AudioClip clip, Vector3 pos, float volume = 1f)
{
var source = pool.Find(s => !s.isPlaying);
if (source == null) return null;
source.transform.position = pos;
source.clip = clip;
source.volume = volume;
source.Play();
return source;
}
}using UnityEngine;
using System.Collections;
public class AudioFader : MonoBehaviour
{
[SerializeField] private AudioSource musicSource;
public void CrossFadeTo(AudioClip newClip, float duration)
{
StartCoroutine(CrossFadeCoroutine(newClip, duration));
}
private IEnumerator CrossFadeCoroutine(AudioClip newClip, float duration)
{
float startVol = musicSource.volume;
float half = duration / 2f;
// Fade out
for (float t = 0f; t < half; t += Time.deltaTime)
{ musicSource.volume = Mathf.Lerp(startVol, 0f, t / half); yield return null; }
// Switch clip and fade in
musicSource.clip = newClip;
musicSource.Play();
for (float t = 0f; t < half; t += Time.deltaTime)
{ musicSource.volume = Mathf.Lerp(0f, startVol, t / half); yield return null; }
musicSource.volume = startVol;
}
}using UnityEngine;
using UnityEngine.Audio;
using UnityEngine.UI;
public class VolumeSettings : MonoBehaviour
{
[SerializeField] private AudioMixer mixer;
[SerializeField] private Slider masterSlider;
void Start()
{
masterSlider.value = PlayerPrefs.GetFloat("MasterVol", 1f);
masterSlider.onValueChanged.AddListener(v => SetVolume("MasterVol", v));
}
// Exposed parameter names must match those set in the Audio Mixer Inspector
private void SetVolume(string param, float linear)
{
float dB = linear > 0.0001f ? Mathf.Log10(linear) * 20f : -80f;
mixer.SetFloat(param, dB);
PlayerPrefs.SetFloat(param, linear);
}
}// Pause all audio globally
AudioListener.pause = true;
// UI sounds can bypass the global pause
uiSource.ignoreListenerPause = true;
// Resume all audio
AudioListener.pause = false;
// Pause/resume a single source (remembers playback position)
musicSource.Pause();
musicSource.UnPause();Only one AudioListener can exist per scene. Remove AudioListener from secondary cameras, or disable/enable them when switching cameras.
// BAD: Play() restarts the clip, cutting off the previous playback
void OnShoot()
{
audioSource.clip = gunshot;
audioSource.Play(); // Interrupts previous gunshot
}
// GOOD: PlayOneShot allows overlapping instances
void OnShoot()
{
audioSource.PlayOneShot(gunshot, 0.8f);
}// BAD: Mixer parameters use decibels, not linear 0-1
mixer.SetFloat("MasterVol", 0.5f); // Almost silent, not half volume
// GOOD: Convert linear to logarithmic decibels
float dB = Mathf.Log10(Mathf.Max(value, 0.0001f)) * 20f;
mixer.SetFloat("MasterVol", dB);Large audio files (music, dialogue) set to Decompress On Load consume massive memory (~10x for Vorbis). Use Streaming for long clips and Compressed In Memory for medium-length clips.
// BAD: spatialBlend defaults to 0 (2D) -- sound ignores 3D position
AudioSource source = gameObject.AddComponent<AudioSource>();
source.clip = explosionClip;
source.Play(); // Plays at full volume regardless of distance
// GOOD: Set spatialBlend to 1 for 3D positioning
source.spatialBlend = 1.0f;
source.minDistance = 1f;
source.maxDistance = 50f;
source.Play();PlayClipAtPoint creates and destroys a temporary GameObject every call. For frequently played sounds (gunshots, footsteps), use an audio pool instead.
Stereo files used as 3D sources waste memory -- stereo channels collapse to mono during 3D spatialization. Enable Force To Mono in import settings for 3D SFX.
| API | Description | Notes |
|---|---|---|
AudioSource.Play() | Plays the assigned clip | Restarts if already playing |
AudioSource.PlayOneShot(clip, vol) | Plays clip without interrupting current | Supports overlapping |
AudioSource.PlayClipAtPoint(clip, pos) | Static: plays at world position | Creates temporary GameObject |
AudioSource.PlayDelayed(delay) | Plays after delay in seconds | |
AudioSource.PlayScheduled(time) | Plays at DSP time | Sample-accurate scheduling |
AudioSource.Stop() | Stops playback | |
AudioSource.Pause() | Pauses playback | Remembers position |
AudioSource.UnPause() | Resumes paused playback | |
AudioSource.isPlaying | Whether source is currently playing | Read-only |
AudioSource.time | Playback position in seconds | Read/write |
AudioSource.timeSamples | Playback position in PCM samples | Read/write |
AudioListener.volume | Global master volume | Static, 0.0-1.0 |
AudioListener.pause | Pause all audio | Static bool |
AudioClip.length | Clip duration in seconds | Read-only |
AudioClip.samples | Clip duration in samples | Read-only |
AudioClip.channels | Number of audio channels | Read-only |
AudioClip.frequency | Sample rate in Hz | Read-only |
AudioClip.loadState | Current load state | Read-only |
AudioClip.Create(name, len, ch, freq, stream) | Creates a runtime AudioClip | |
AudioClip.GetData(data, offset) | Reads sample data into array | |
AudioClip.SetData(data, offset) | Writes sample data from array | |
AudioClip.LoadAudioData() | Loads clip data into memory | |
AudioClip.UnloadAudioData() | Unloads clip data from memory | |
AudioMixer.SetFloat(name, val) | Sets exposed parameter | Returns false if not found |
AudioMixer.GetFloat(name, out val) | Gets exposed parameter value | Returns false if not found |
AudioMixer.ClearFloat(name) | Resets parameter to snapshot value | |
AudioMixer.FindSnapshot(name) | Finds snapshot by exact name | Returns AudioMixerSnapshot |
AudioMixer.FindMatchingGroups(path) | Finds groups by path pattern | Returns AudioMixerGroup[] |
AudioMixer.TransitionToSnapshots(snaps, weights, time) | Weighted snapshot blend | |
AudioMixerSnapshot.TransitionTo(time) | Transitions to this snapshot |
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.