using UnityEngine;
namespace HotUpdate.Gameplay
{
/// Order matches the clips serialized on the UiSfx prefab (Ui_Click … Ui_Notify).
public enum UiSound { Click, Confirm, Back, Open, Close, Tab, Claim, Deny, Toggle, Notify }
/// One-shot UI feedback from the authored UiSfx prefab; obeys the SFX setting, independent of music.
public sealed class UiSfx : MonoBehaviour
{
public const string PrefabName = "UiSfx";
public const string PrefabFolder = "Assets/Bundles/Sound/Prefab";
// Ignore the same sound re-requested within this window (e.g. a refresh firing twice in one frame).
const float RepeatGuard = .06f;
[SerializeField] AudioSource _source;
[SerializeField] AudioClip[] _clips;
static UiSfx _instance;
UiSound _last;
float _lastAt = -1;
public AudioSource Source => _source;
public AudioClip Clip(UiSound sound) => _clips != null && (int)sound < _clips.Length ? _clips[(int)sound] : null;
void OnEnable() { _instance = this; }
void OnDisable() { if (_instance == this) _instance = null; }
public static void Play(UiSound sound)
{
var player = _instance;
if (player == null || player._source == null || !PrototypeClientPrefs.Sfx) return;
var clip = player.Clip(sound);
if (clip == null) return;
float now = Time.unscaledTime;
if (sound == player._last && now - player._lastAt < RepeatGuard) return;
player._last = sound; player._lastAt = now;
player._source.PlayOneShot(clip);
}
/// Button names from the UI JSON decide the feedback; anything unlisted is a plain click.
public static UiSound ForButton(string name)
{
if (name == "Back" || name == "Home" || name == "Close") return UiSound.Close;
if (name == "CancelPreview" || name == "RemovePet" || name == "Abandon") return UiSound.Back;
if (name.Contains("Tab") || name == "MailPrev" || name == "MailNext") return UiSound.Tab;
if (name.StartsWith("Toggle") || name == "CycleQuality") return UiSound.Toggle;
return UiSound.Click;
}
}
}