170 lines
5.5 KiB
C#
170 lines
5.5 KiB
C#
|
|
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<AudioClip> dayPlaylist;
|
||
|
|
[Tooltip("Music tracks played during the night (20:00 - 08:00).")]
|
||
|
|
[SerializeField] private List<AudioClip> 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<AudioSource>();
|
||
|
|
if (sfxSource == null) sfxSource = gameObject.AddComponent<AudioSource>();
|
||
|
|
|
||
|
|
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<AudioClip> 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);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|