Skip to main content

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/PlaySound randomizes the AudioSource's pitch between 0.95 and 1.05 before playing, to prevent "machine-gun" repetition fatigue. This happens unconditionally, inside HookAudioManager itself — it's independent of any profile setting (see the note under HookButtonAudioProfile below).
  • 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) → plays Profile.HoverSound. Debounced with a 0.05s cooldown so rapid re-hovers don't spam the source.
  • Click (OnClick) → plays Profile.ClickSound.
  • Press-down (OnRequestPress) → plays Profile.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 → plays Profile.OnShowSound.
  • OnHideStarted → plays Profile.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: PitchRandomness is declared on the profile but is not currently read or applied anywhere in HookButtonAudio. Pitch variance you hear on button sounds comes entirely from HookAudioManager's own internal randomization (0.95–1.05), not from this field. Don't rely on tuning PitchRandomness to 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​

  1. Add HookButtonAudio to the same GameObject as your HookButton (or HookViewAudio alongside a HookView).
  2. Create a profile asset: Assets > Create > HookUI > Audio > Button Profile (or View Profile).
  3. Assign clips (and Volume) on the profile asset.
  4. 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.MasterVolume to wire up your Settings Menu volume slider.