Pepper.SFX
All Guidance pages

Guidance / Start here

Quick Start

Choose Your Path

Pick the setup method that fits your workflow:

Method 1: Quick Wizard ⭐ (2 minutes)

Best for: Beginners, rapid prototyping Time: 2 minutes Skill: Easy

Jump to Quick Wizard

Method 2: Manual Setup (10 minutes)

Best for: Learning the system, custom control Time: 10 minutes Skill: Medium

Jump to Manual Setup

Method 3: Registry System (Advanced)

Best for: Large projects, eliminating Resources folder Time: Setup + migration Skill: Advanced

See Migration for full details.


Method 1: Quick Wizard

The absolute fastest way to add sounds - perfect for beginners!

Step 1: Add AudioManager to Scene (30 seconds)

  1. Create empty GameObject in your scene
  2. Add AudioManager component
  3. Done! (Auto-configures itself)

Step 2: Create Sound Assets (1 minute)

  1. In Unity menu: Window > Audio System > Sound Builder (Simple)
  2. Choose Creation Mode:
    • Complete Setup - Creates Bus + Container + Event all at once (recommended)
    • Container Only - Just create a container
    • Event Only - Just create an event (with existing container or blank)
    • Bus Only - Just create a bus
    • Batch Import - Import multiple clips at once
  3. Enter sound name (e.g., “ButtonClick”)
  4. Select Container Type:
    • Routing - Direct playback (plays all clips simultaneously if multiple added)
    • Random - Random selection with weights
    • Sequence - Sequential playback (Forward/Reverse/PingPong)
    • Switch - Switch-based selection
    • Blend - RTPC-driven real-time blending
  5. Add one or more AudioClips
  6. Configure advanced options if needed (pitch/volume randomization, 3D settings)
  7. Click “Create Complete Sound Setup”

There are no presets: you set each option yourself, and the defaults suit a simple 2D sound effect.

✅ Done! The wizard creates:

  • AudioBus (with custom name)
  • Container (any type: Routing, Random, Sequence, Switch, or Blend)
  • AudioEvent (with selectable action type)
  • All references pre-filled

💡 Pro Tips:

  • The wizard auto-detects selected audio clips and suggests batch import for multiple selections
  • Use “Auto-Create Standard Folder Structure” to set up all required folders
  • Routing containers can layer multiple clips for complex sounds (e.g., gunshot with shell eject)

Step 3: Play in Code (30 seconds)

using AudioSystem;

public class MyScript : MonoBehaviour
{
    public AudioEvent buttonClickSound;

    void OnButtonPressed()
    {
        buttonClickSound.Post(gameObject, transform.position);
    }
}

Drag the created AudioEvent into the script field, and you’re done!

What’s Next? See the Cookbook chapter for more recipes or jump to Troubleshooting.


Method 2: Manual Setup

Traditional workflow - full control over every step

Step 1: Add AudioManager (2 minutes)

  1. In your scene, create a new empty GameObject
  2. Name it “AudioManager”
  3. Add the AudioManager component
  4. Leave all default settings - they’re optimized for most games

Inspector Settings (defaults are fine):

  • Master Volume: 1.0
  • Max Real Voices: 32
  • Max Virtual Voices: 64
  • Enable LOD: ✓

Occlusion is opted into per-container via the Use Occlusion toggle on AudioContainer assets, not via a global AudioManager switch — see the Occlusion chapter in the Manual.

Important: AudioManager persists between scenes automatically via DontDestroyOnLoad, as long as Persist Across Scenes is on (the default) and its GameObject is at the top of the hierarchy: Unity keeps only root objects. To keep it under another object (a scene that is never unloaded, a client-only root), turn Persist Across Scenes off; it then belongs to its own scene.


Step 2: Create Folder Structure (1 minute)

Right-click in Project window → Create > Audio System > Sound Builder (Simple) → Click “Auto-Create Standard Folder Structure”

Or manually create:

Assets/Audio/
├── Resources/
│   └── Audio/
│       ├── Events/    ← AudioEvents MUST go here
│       └── States/    ← AudioStates MUST go here
├── Containers/        ← Container assets
├── Buses/             ← Bus assets
└── AudioClips/        ← Your .wav/.mp3 files
    ├── SFX/
    ├── Music/
    └── Ambience/

Why Resources folder? AudioManager auto-loads Events and States from Resources/Audio/Events and Resources/Audio/States at startup. (See the Migration chapter to skip this requirement via AudioEventRegistry.)


Step 3: Create Your First Bus (2 minutes)

  1. Right-click in Assets/Audio/Buses/
  2. Select Create > Audio System > Audio Bus
  3. Name the file: “SFX_Bus”
  4. Select it and configure in the Inspector:
    • Bus Name: “SFX”
    • Volume Db: 0
    • Parent Bus: (leave empty for now)
    • Mixer Group: (optional)

What just happened? You created a volume control group for sound effects. Later you can adjust all SFX together.

💡 Tip: The Quick Wizard creates this automatically in its Complete Setup mode.


Step 4: Create Your First Container (2 minutes)

  1. Right-click in Assets/Audio/Containers/
  2. Select Create > Audio System > Routing Container
  3. Name it: “TestSound_RC”
  4. Select it and configure in the Inspector:
    • Container Name: “TestSound”
    • Audio Clips: Drag in 1-3 AudioClips from your project
    • Volume: 1.0
    • Loop: ☐ (unchecked)

Optional - Add Variation:

  • Enable Volume Randomization: ☑
    • Min: -1, Max: 1
  • Enable Pitch Randomization: ☑
    • Min: -50, Max: 50

What just happened? You created a simple container that plays your clip(s) with optional randomization.


Step 5: Create Your First Event (2 minutes)

  1. Right-click in Assets/Audio/Resources/Audio/Events/
  2. Select Create > Audio System > Audio Event
  3. Name it: “Play_TestSound”
  4. Select it and configure in the Inspector:

Event Configuration:

  • Event Name: “Play_TestSound”

Voice Settings:

  • Priority: Medium
  • Max Instances: 5
  • Cooldown: 0

Actions → Size: 1

Action [0]:

  • Type: Play
  • Container: TestSound_RC (drag from Containers folder)
  • Target Bus: SFX_Bus (drag from Buses folder)
  • Delay: 0
  • Fade Duration: 0

What just happened? You created an event that plays your container through the SFX bus when triggered.

⚠️ Important: The Inspector will show a warning if the event is not in the Resources folder. Click the “Move to Resources” button if you see this warning.


Step 6: Play It From Code (1 minute)

Create a new C# script called TestAudio.cs:

using UnityEngine;
using AudioSystem;

public class TestAudio : MonoBehaviour
{
    [SerializeField] private AudioEvent testEvent;

    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space))
        {
            testEvent.Post(gameObject, transform.position);
            Debug.Log("Playing test sound!");
        }
    }
}

Setup:

  1. Create a new GameObject in your scene (or use an existing one)
  2. Attach the TestAudio script to it
  3. In the Inspector, drag Play_TestSound event into the Test Event field
  4. Press Play in Unity
  5. Press Spacebar to hear your sound!

🎉 Congratulations!

You’ve successfully set up the complete audio pipeline:

Your Code → AudioEvent → Container → Voice → Bus → Speaker


Troubleshooting

“AudioEvent not playing!”

Check Inspector warnings:

  • Open your AudioEvent asset
  • Look for red/yellow warning boxes
  • If it says “NOT in Resources folder” → Click “Move to Resources/Audio/Events/”

“AudioManager not found!”

  • Ensure AudioManager is in scene
  • Check it persists: with Persist Across Scenes on (the default) it is kept across scenes, but only if its GameObject is a root (Unity warns otherwise). Under a parent, turn Persist Across Scenes off and keep it in a scene that stays loaded.

“No AudioEvents found in Resources/Audio/Events”

Sound Too Quiet/Loud?

Check:

  1. Container volume (0-1)
  2. Bus volume (in dB, 0 = no change)
  3. Master volume on AudioManager
  4. Unity’s AudioListener volume

Quick Reference

Minimal Code Example

using AudioSystem;

public AudioEvent mySound;

void Start()
{
    mySound.Post(gameObject, transform.position);
}

Common Methods

Play a sound:

AudioHandle handle = myEvent.Post();
AudioHandle handle = myEvent.Post(gameObject, transform.position);

Control playback:

handle.Stop(fadeTime: 0.5f);
handle.Pause();
handle.Resume();
handle.SetVolumeScale(0.75f);   // relative to the authored volume
handle.SetPitchOffset(2f);      // semitones, on top of the authored pitch

Global controls:

AudioManager.Instance.StopAllSounds();
AudioManager.Instance.PauseAll();
AudioManager.Instance.UnpauseAll();
AudioManager.Instance.MuteAll(true);   // mute
AudioManager.Instance.MuteAll(false);  // unmute
worldBus.Pause();                      // a game's pause: this bus and its children hold, a pause menu's buses play
worldBus.Resume();

Bus control:

AudioManager.Instance.SetBusVolume("Music", volumeDb: -6f, transitionTime: 1f);

State changes:

AudioManager.Instance.SetState("Underwater", transitionTime: 1.5f);

RTPC with transitions:

AudioManager.Instance.SetRTPC("CombatIntensity", 0.75f);
AudioManager.Instance.TransitionRTPC("CombatIntensity", 1.0f, duration: 2f);

What’s Next?

Level 1 - You are here! ✓

  • Basic sound playback
  • Simple events and containers
  • Bus volume control

Level 2 - Cookbook

  • Footsteps with variations
  • UI sound systems
  • Weapon audio
  • Music systems
  • 3D spatial audio

Level 3 - Manual

  • Deep system understanding
  • Advanced features
  • Performance optimization
  • Registry system

Level 4 - API Reference

  • Complete API documentation
  • All classes and methods
  • Advanced use cases

Comparison: Which Method Should I Use?

Method Best For Setup Time Flexibility Learning
Quick Wizard Beginners, rapid prototyping 2 min Low Easy
Manual Setup Learning system, custom control 10 min Medium Best
Registry System Large projects, no Resources 15 min High Advanced

Recommendation:

  • New users: Start with Quick Wizard
  • Learning the system: Use Manual Setup
  • After 10+ sounds: Consider Registry System (see Migration)

Key Concepts to Remember

  1. Events are in Resources - Must be in Assets/Audio/Resources/Audio/Events/ to auto-load (or use registry)
  2. States are in Resources - Must be in Assets/Audio/Resources/Audio/States/ to auto-load (or use registry)
  3. One AudioManager per project - It persists between scenes
  4. Buses use dB - 0 dB = no change, -6 dB ≈ half as loud, -80 dB = silence
  5. Voice limit - 32 real voices by default (configurable)

🆕 Ambient Propagation (v2.3.0)

Pepper.SFX now ships with an optional zone/portal-based ambient propagation subsystem. Use it when you want ambient beds (rain, wind, machinery) to route through geometry — muffled through a closed door, swelling as it opens, heard from the window when the listener is in another room.

Propagation is additive — it doesn’t touch the SFX event pipeline you just learned. Skip this section if your project only plays discrete SFX.

2-Minute Setup

1. Create empty GameObject → BoxCollider (isTrigger forced on) → Add "Audio/Propagation/Audio Zone"
   → Size collider to fit the room. Repeat for each acoustic space.

2. Create empty GameObject at a doorway → BoxCollider → Add "Audio/Propagation/Audio Portal"
   → Drag the two adjacent AudioZones into ZoneA and ZoneB.

3. Create empty GameObject inside the source zone → Add "Audio/Propagation/Ambient Source"
   → Assign Source Zone, Looping Clip, and Ambience Mixer Group.

4. On your player object, the one with the Collider (e.g. the player root's Capsule Collider)
   → Add "Audio/Propagation/Audio Listener Zone Tracker". Not on the camera that holds the
   AudioListener: trigger events only reach a GameObject that has a Collider.
   (A kinematic Rigidbody is auto-added if needed for trigger events.)

That’s it. The PropagationManager auto-instantiates on first reference. Walk through the doorway and you’ll hear the bed transition smoothly between zones.

Door-Driven Transmission

To let a door swing affect audio, implement IPortalDoorSource on any MonoBehaviour:

using AudioSystem.Propagation;

public class MyDoor : MonoBehaviour, IPortalDoorSource
{
    public float OpenProgress => animator.GetFloat("openAmount"); // 0..1
    public event System.Action OnChanged;
}

Drag it into the portal’s Door Source field. Closed → closedTransmission amplitude + closedLowPassHz filtering; open → the base values. Interpolation is continuous — no discrete snap.

Where to Learn More

From the Pepper.SFX 3.1 guides (USER_GUIDE.md). Something wrong or unclear? Tell me.