Guidance / Cookbook
UI Sounds
Recipe: Button Click Sound
📋 What: Button with click sound and subtle variations
🎯 Use Case: UI buttons, menu navigation
Asset Setup
1. Create Container:
- Right-click
Containers/UI/→ Create → Random Container - Name: “UI_ButtonClick_RnC”
- Inspector:
- Audio Clips: Add 2-3 click sound variations
- Avoid Repeat Last: 1
- Use Weighting: ✓ (all weights = 1.0)
- Volume: 0.8
- Enable Volume Randomization: ✓ (Min: -1, Max: 1)
- Enable Pitch Randomization: ✓ (Min: -50, Max: 50)
2. Create Event:
- Right-click
Assets/Resources/Audio/Events/UI/→ Create → Audio Event - Name: “Play_UI_ButtonClick”
- Inspector:
- Event Name: “Play_UI_ButtonClick”
- Priority: Critical
- Max Instances: 2
- Steal Behavior: Oldest
- Cooldown: 0.05
- Actions → Size: 1
- Action [0]:
- Type: Play
- Container: UI_ButtonClick_RnC
- Target Bus: UI_Bus
Code
using UnityEngine;
using UnityEngine.UI;
using AudioSystem;
public class UIButtonSound : MonoBehaviour
{
[SerializeField] private AudioEvent clickEvent;
private Button button;
void Awake()
{
button = GetComponent<Button>();
if (button != null)
{
button.onClick.AddListener(OnButtonClick);
}
}
void OnDestroy()
{
if (button != null)
{
button.onClick.RemoveListener(OnButtonClick);
}
}
void OnButtonClick()
{
if (clickEvent != null)
{
clickEvent.Post();
}
}
}
Usage:
- Attach to Button GameObject
- Drag “Play_UI_ButtonClick” into Click Event field
- Click button to hear sound
✅ Result: Button clicks with subtle variation, no spam!
Recipe: Settings Menu with Volume Sliders
📋 What: Complete audio settings menu with persistence
🎯 Use Case: Options menu, settings screen
💻 Code:
using UnityEngine;
using UnityEngine.UI;
using AudioSystem;
public class AudioSettingsMenu : MonoBehaviour
{
[Header("UI References")]
[SerializeField] private Slider masterSlider;
[SerializeField] private Slider sfxSlider;
[SerializeField] private Slider musicSlider;
[SerializeField] private Slider dialogueSlider;
[Header("Audio Events")]
[SerializeField] private AudioEvent testSFXEvent;
private const string MASTER_KEY = "Audio_MasterVolume";
private const string SFX_KEY = "Audio_SFXVolume";
private const string MUSIC_KEY = "Audio_MusicVolume";
private const string DIALOGUE_KEY = "Audio_DialogueVolume";
void Start()
{
LoadSettings();
SetupListeners();
ApplySettings();
}
void LoadSettings()
{
masterSlider.value = PlayerPrefs.GetFloat(MASTER_KEY, 1f);
sfxSlider.value = PlayerPrefs.GetFloat(SFX_KEY, 1f);
musicSlider.value = PlayerPrefs.GetFloat(MUSIC_KEY, 1f);
dialogueSlider.value = PlayerPrefs.GetFloat(DIALOGUE_KEY, 1f);
}
void SetupListeners()
{
masterSlider.onValueChanged.AddListener(OnMasterVolumeChanged);
sfxSlider.onValueChanged.AddListener(OnSFXVolumeChanged);
musicSlider.onValueChanged.AddListener(OnMusicVolumeChanged);
dialogueSlider.onValueChanged.AddListener(OnDialogueVolumeChanged);
}
void ApplySettings()
{
OnMasterVolumeChanged(masterSlider.value);
OnSFXVolumeChanged(sfxSlider.value);
OnMusicVolumeChanged(musicSlider.value);
OnDialogueVolumeChanged(dialogueSlider.value);
}
void OnMasterVolumeChanged(float value)
{
AudioManager.Instance.SetMasterVolume(value);
PlayerPrefs.SetFloat(MASTER_KEY, value);
PlayerPrefs.Save();
}
void OnSFXVolumeChanged(float value)
{
SetPlayerVolume("SFX", value);
PlayerPrefs.SetFloat(SFX_KEY, value);
PlayerPrefs.Save();
}
void OnMusicVolumeChanged(float value)
{
SetPlayerVolume("Music", value);
PlayerPrefs.SetFloat(MUSIC_KEY, value);
PlayerPrefs.Save();
}
void OnDialogueVolumeChanged(float value)
{
SetPlayerVolume("Dialogue", value);
PlayerPrefs.SetFloat(DIALOGUE_KEY, value);
PlayerPrefs.Save();
}
// The player's volume on a bus (Manual §6.8): on top of the mix, never saved into the bus asset,
// and a mix state can't undo it. Not SetBusVolume, which changes the bus's own Volume.
void SetPlayerVolume(string busName, float linear)
{
var bus = AudioManager.Instance.GetBus(busName); // an unknown name warns once
if (bus != null)
bus.PlayerVolumeDb = AudioSystem.AudioExtensions.LinearToDb(linear); // qualified: Unity 6.3 has its own AudioExtensions
}
// Call this from a "Test" button
public void PlayTestSound()
{
if (testSFXEvent != null)
{
testSFXEvent.Post();
}
}
}
UI Setup:
- Create 4 Sliders (Master, SFX, Music, Dialogue)
- Set slider range: 0 to 1
- Create “Test Sound” button
- Attach script to settings panel
- Assign references
✅ Result: Full audio settings with persistence and test button!
💡 Why PlayerVolumeDb and not SetBusVolume: SetBusVolume changes the bus’s own Volume, the mix you authored. In the editor a Play-mode change stays in the asset, and a state that sets the bus’s level overwrites the player’s choice. The player’s volume is a separate level on top. Example08_AudioSettingsUI is the full version.
From the Pepper.SFX 3.1 guides (USER_GUIDE.md). Something wrong or unclear? Tell me.