agentsclimarketplace

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

Install
npx -y skills add XeldarAlz/everything-claude-unity --skill audio

Assembled 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 radius
  • maxDistance: silence radius
  • rolloffMode: Logarithmic (realistic) or Custom (AnimationCurve)
  • spread: 0 = point source, 360 = omnidirectional

Compression Per Platform

TypeFormatLoad TypeUse
MusicVorbis (quality 40-60%)StreamingBackground music
SFX (short)ADPCMDecompress On LoadGunshots, jumps
SFX (long)Vorbis (quality 70%)Compressed In MemoryAmbient loops
UIPCM (uncompressed)Decompress On LoadButton 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 AudioListener per scene (usually on the camera)
  • Pool AudioSources for one-shot SFX — don't create/destroy
  • Use Time.unscaledDeltaTime for audio during pause

Keep looking

Skills are one crate of 627,801. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.