using System; using Cysharp.Threading.Tasks; using PrimeTween; using UnityEngine; namespace DanieleMarotta.RiversongCodeShowcase { [GameSystemGroup(typeof(AudioSystemGroup))] public class BackgroundMusicSystem : GameSystem, IInitializable, IDisposable { [InjectService] private GameConfig _config; [InjectService] private IScene _scene; [InjectService] private ISignalBus _signalBus; private AudioSource _audioSource; private AudioClip _mainThemeClip; private AudioClip _gameplayClip; public BackgroundMusicSystem(IServiceLocator serviceLocator) : base(serviceLocator) { } public async UniTask InitializeAsync() { _audioSource = new GameObject("BGM").AddComponent(); _audioSource.transform.SetParent(_scene.SceneFolders.AudioSources); _audioSource.playOnAwake = false; _audioSource.loop = true; _mainThemeClip = await _config.Audio.MainThemeClip.LoadAssetAsync(); _gameplayClip = await _config.Audio.GameplayClip.LoadAssetAsync(); _signalBus.Subscribe(OnGameInitializationCompleted); _signalBus.Subscribe(OnGameStarted); _signalBus.Subscribe(OnWorldReady); } public void Dispose() { _signalBus.Unsubscribe(OnGameInitializationCompleted); _signalBus.Unsubscribe(OnGameStarted); _signalBus.Unsubscribe(OnWorldReady); } private void OnGameInitializationCompleted(GameInitializationCompletedSignal signal) { Play(_mainThemeClip, _config.Audio.MainThemeVolume); } private void OnGameStarted(GameStartedSignal signal) { _ = FadeOutAsync(2); } private async UniTask FadeOutAsync(float duration) { await Tween.Custom(_audioSource.volume, 0, duration, value => _audioSource.volume = value, Ease.Linear); } private void OnWorldReady(WorldReadySignal signal) { Play(_gameplayClip, _config.Audio.GameplayVolume); } private void Play(AudioClip clip, float volume) { _audioSource.Stop(); _audioSource.clip = clip; _audioSource.volume = volume; _audioSource.Play(); } } }