Audio
Skill XeldarAlz/everything-claude-unity/.claude/skills/systems/audio
Unity audio system — AudioMixer groups, snapshots, spatial audio, audio source pooling, compression per platform.From its SKILL.md
npx -y skills add XeldarAlz/everything-claude-unity --skill audioAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 20 stars20 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
SKILL.md
4.1 KB, as published. Nobody here has run it
Audio System
AudioMixer Setup
Master (exposed: "MasterVolume")
├── Music (exposed: "MusicVolume")
├── SFX (exposed: "SFXVolume")
│ ├── Weapons
│ ├── Environment
│ └── UI
└── Voice (exposed: "VoiceVolume")
Volume Control via Exposed Parameters
[SerializeField] private AudioMixer _mixer;
public void SetMasterVolume(float normalizedValue)
{
// Convert 0-1 slider to decibels (-80 to 0)
float dB = normalizedValue > 0.001f
? Mathf.Log10(normalizedValue) * 20f
: -80f;
_mixer.SetFloat("MasterVolume", dB);
}
Snapshots
// Transition between snapshots for ambient changes
_underwaterSnapshot.TransitionTo(0.5f); // Muffle audio underwater
_defaultSnapshot.TransitionTo(1.0f); // Return to normal
Playing Sounds
// One-shot SFX (fire and forget, doesn't interrupt)
_audioSource.PlayOneShot(_explosionClip, 0.8f);
// Music (interruptible, one at a time per source)
_musicSource.clip = _battleMusic;
_musicSource.Play();
Audio Source Pooling
public sealed class SFXPool : MonoBehaviour
{
[SerializeField] private int _poolSize = 16;
[SerializeField] private AudioMixerGroup _sfxGroup;
private AudioSource[] _sources;
private int _nextIndex;
private void Awake()
{
_sources = new AudioSource[_poolSize];
for (int i = 0; i < _poolSize; i++)
{
GameObject obj = new GameObject($"SFX_{i}");
obj.transform.SetParent(transform);
AudioSource source = obj.AddComponent<AudioSource>();
source.outputAudioMixerGroup = _sfxGroup;
source.playOnAwake = false;
_sources[i] = source;
}
}
public void PlayAt(AudioClip clip, Vector3 position, float volume = 1f)
{
AudioSource source = _sources[_nextIndex];
_nextIndex = (_nextIndex + 1) % _poolSize;
source.transform.position = position;
source.spatialBlend = 1f; // 3D
source.PlayOneShot(clip, volume);
}
}
Spatial Audio
spatialBlend: 0 = 2D (UI, music), 1 = 3D (world SFX)minDistance: full volume radiusmaxDistance: silence radiusrolloffMode: Logarithmic (realistic) or Custom (AnimationCurve)spread: 0 = point source, 360 = omnidirectional
Compression Per Platform
| Type | Format | Load Type | Use |
|---|---|---|---|
| Music | Vorbis (quality 40-60%) | Streaming | Background music |
| SFX (short) | ADPCM | Decompress On Load | Gunshots, jumps |
| SFX (long) | Vorbis (quality 70%) | Compressed In Memory | Ambient loops |
| UI | PCM (uncompressed) | Decompress On Load | Button clicks |
Music System Pattern
public sealed class MusicManager : MonoBehaviour
{
[SerializeField] private AudioSource _sourceA;
[SerializeField] private AudioSource _sourceB;
[SerializeField] private float _crossfadeDuration = 2f;
private AudioSource _activeSource;
public void CrossfadeTo(AudioClip newClip)
{
AudioSource incoming = _activeSource == _sourceA ? _sourceB : _sourceA;
incoming.clip = newClip;
incoming.volume = 0f;
incoming.Play();
StartCoroutine(Crossfade(_activeSource, incoming));
_activeSource = incoming;
}
private IEnumerator Crossfade(AudioSource outgoing, AudioSource incoming)
{
float elapsed = 0f;
while (elapsed < _crossfadeDuration)
{
elapsed += Time.unscaledDeltaTime;
float t = elapsed / _crossfadeDuration;
outgoing.volume = 1f - t;
incoming.volume = t;
yield return null;
}
outgoing.Stop();
}
}
Key Rules
- One
AudioListenerper scene (usually on the camera) - Pool AudioSources for one-shot SFX — don't create/destroy
- Use
Time.unscaledDeltaTimefor audio during pause