using System.Collections; using System.Collections.Generic; using UnityEngine; namespace MedievalShopkeeper { public class AudioManager : MonoBehaviour { public static AudioManager Instance { get; private set; } [Header("Audio Sources")] [Tooltip("Source for background music.")] [SerializeField] private AudioSource bgmSource; [Tooltip("Source for sound effects.")] [SerializeField] private AudioSource sfxSource; [Header("Playlists")] [Tooltip("Music tracks played during the day (08:00 - 20:00).")] [SerializeField] private List dayPlaylist; [Tooltip("Music tracks played during the night (20:00 - 08:00).")] [SerializeField] private List nightPlaylist; [Tooltip("Music played when a Shoplifter or Raider is active in the shop!")] [SerializeField] private AudioClip actionMusic; [Header("Sound Effects")] [SerializeField] private AudioClip saleSFX; [SerializeField] private AudioClip buyStockSFX; [SerializeField] private AudioClip buildSFX; [SerializeField] private AudioClip destroySFX; [SerializeField] private AudioClip repairSFX; [SerializeField] private AudioClip alertSFX; private int activeThreats = 0; private bool isNightTime = false; // Track the current index in each playlist private int currentDayTrack = 0; private int currentNightTrack = 0; private void Awake() { if (Instance != null && Instance != this) { Destroy(gameObject); return; } Instance = this; DontDestroyOnLoad(gameObject); } private void Start() { if (bgmSource == null) bgmSource = gameObject.AddComponent(); if (sfxSource == null) sfxSource = gameObject.AddComponent(); bgmSource.loop = false; if (GameManager.Instance != null) { // Hook into GameManager events GameManager.Instance.OnTimeChanged += CheckDayNight; GameManager.Instance.OnRandomEventTriggered += (e) => PlayAlert(); // Initialize state isNightTime = (GameManager.Instance.CurrentHour >= 20 || GameManager.Instance.CurrentHour < 8); } PlayNextBGM(); } private void Update() { // Automatically play the next track if the current one finishes (and we aren't looping action music) if (bgmSource != null && !bgmSource.isPlaying && bgmSource.clip != null && activeThreats == 0) { PlayNextBGM(); } } private void CheckDayNight(int hour, int minute) { bool isNowNight = (hour >= 20 || hour < 8); if (isNowNight != isNightTime) { isNightTime = isNowNight; // Only swap music immediately if we aren't currently in combat/raid mode if (activeThreats == 0) { PlayNextBGM(); } } } public void AddThreat() { activeThreats++; if (activeThreats == 1) // Switched from 0 to 1 { PlayActionMusic(); } } public void RemoveThreat() { activeThreats = Mathf.Max(0, activeThreats - 1); if (activeThreats == 0) { // The threat is over, return to normal playlist PlayNextBGM(); } } private void PlayActionMusic() { if (actionMusic == null || bgmSource == null) return; bgmSource.Stop(); bgmSource.clip = actionMusic; bgmSource.loop = true; // Action music loops continuously until the threat is gone bgmSource.Play(); } private void PlayNextBGM() { if (bgmSource == null) return; bgmSource.loop = false; bgmSource.Stop(); List activePlaylist = isNightTime ? nightPlaylist : dayPlaylist; if (activePlaylist == null || activePlaylist.Count == 0) return; // Choose the correct index based on time of day if (isNightTime) { if (currentNightTrack >= activePlaylist.Count) currentNightTrack = 0; bgmSource.clip = activePlaylist[currentNightTrack]; currentNightTrack++; } else { if (currentDayTrack >= activePlaylist.Count) currentDayTrack = 0; bgmSource.clip = activePlaylist[currentDayTrack]; currentDayTrack++; } bgmSource.Play(); } // --- SFX Triggers --- public void PlaySale() => PlaySFX(saleSFX); public void PlayBuyStock() => PlaySFX(buyStockSFX); public void PlayBuild() => PlaySFX(buildSFX); public void PlayDestroy() => PlaySFX(destroySFX); public void PlayRepair() => PlaySFX(repairSFX); public void PlayAlert() => PlaySFX(alertSFX); private void PlaySFX(AudioClip clip) { if (clip != null && sfxSource != null) { sfxSource.PlayOneShot(clip); } } } }