Audio System
A good UI feels "crunchy" and responsive. Audio is 50% of that feel. HookUI includes a singleton manager and components to make UI audio effortless.
HookAudioManager
The core singleton. It persists across scene loads.
Features
- Pitch Variation: Every call to
Play/PlaySoundrandomizes theAudioSource's pitch between 0.95 and 1.05 before playing, to prevent "machine-gun" repetition fatigue. This happens unconditionally, insideHookAudioManageritself — it's independent of any profile setting (see the note underHookButtonAudioProfilebelow). - Master Volume: Global slider to control UI volume.
- Static Access: Call it from anywhere.
HookAudioManager.Play(myClip, 1.0f);
Attaching a Voice to a HookView or HookButton
Rather than calling HookAudioManager.Play(...) manually from your own scripts, you can attach a small component to a HookView or HookButton and let it react to that view/button's own lifecycle events automatically.
HookButtonAudio
// Runtime/Scripts/Components/HookButtonAudio.cs — [RequireComponent(typeof(HookButton))]
public class HookButtonAudio : MonoBehaviour
{
public HookButtonAudioProfile Profile { get; set; }
}
Wired automatically via the HookButton on the same GameObject:
- Hover (
OnRequestHighlight) → playsProfile.HoverSound. Debounced with a 0.05s cooldown so rapid re-hovers don't spam the source. - Click (
OnClick) → playsProfile.ClickSound. - Press-down (
OnRequestPress) → playsProfile.PressSound.
HookViewAudio
// Runtime/Scripts/Components/HookViewAudio.cs — [RequireComponent(typeof(HookView))]
public class HookViewAudio : MonoBehaviour
{
public HookViewAudioProfile Profile { get; set; }
}
Wired automatically via the HookView on the same GameObject:
OnShowStarted→ playsProfile.OnShowSound.OnHideStarted→ playsProfile.OnHideSound.
Audio Profiles
Profiles are ScriptableObjects so one asset can be shared across many buttons/views.
// Runtime/Scripts/Data/HookButtonAudioProfile.cs
// [CreateAssetMenu(menuName = "HookUI/Audio/Button Profile")]
public class HookButtonAudioProfile : ScriptableObject
{
public AudioClip HoverSound;
public AudioClip ClickSound;
public AudioClip PressSound;
[Range(0f, 1f)] public float Volume = 1f;
[Range(0.8f, 1.2f)] public float PitchRandomness = 0.05f;
}
Known gap:
PitchRandomnessis declared on the profile but is not currently read or applied anywhere inHookButtonAudio. Pitch variance you hear on button sounds comes entirely fromHookAudioManager's own internal randomization (0.95–1.05), not from this field. Don't rely on tuningPitchRandomnessto change anything yet.
// Runtime/Scripts/Data/HookViewAudioProfile.cs
// [CreateAssetMenu(menuName = "HookUI/Audio/View Profile")]
public class HookViewAudioProfile : ScriptableObject
{
public AudioClip OnShowSound;
public AudioClip OnHideSound;
[Range(0f, 1f)] public float Volume = 1f;
}
Setup
- Add
HookButtonAudioto the same GameObject as yourHookButton(orHookViewAudioalongside aHookView). - Create a profile asset: Assets > Create > HookUI > Audio > Button Profile (or View Profile).
- Assign clips (and Volume) on the profile asset.
- Drag the profile onto the component's Profile field in the Inspector.
Reuse one profile across every button that should sound the same — you don't need a profile per button.
Best Practices
- Use short, punchy sounds for UI (clicks, swooshes).
- Use
HookAudioManager.Instance.MasterVolumeto wire up your Settings Menu volume slider.