Files
riversong-code-showcase/Source/Riversong/Game/Audio/PlaySoundOnEventSystem.cs
2026-05-21 16:04:49 +02:00

121 lines
4.6 KiB
C#

using System;
using System.Collections.Generic;
using Cysharp.Threading.Tasks;
using Unity.Mathematics;
using Time = UnityEngine.Time;
namespace DanieleMarotta.RiversongCodeShowcase
{
public class PlaySoundOnEventSystem : GameSystem, IInitializable, IDisposable
{
[InjectService]
private ISoundPlayer _soundPlayer;
[InjectService]
private ISignalBus _signalBus;
[InjectService]
private IGameDatabase _gameDatabase;
[InjectService]
private ITileSpace _tileSpace;
private Dictionary<int, float> _soundPlayedTimestamps = new();
public PlaySoundOnEventSystem(IServiceLocator serviceLocator) : base(serviceLocator)
{
}
public UniTask InitializeAsync()
{
_signalBus.Subscribe<BuildingPlacementAnimationCompletedSignal>(OnBuildingPlacementAnimationCompleted);
_signalBus.Subscribe<ConstructionSiteDeletedSignal>(OnConstructionSiteDeleted);
_signalBus.Subscribe<BuildingDeletedSignal>(OnBuildingDeleted);
_signalBus.Subscribe<BuildingUpgradedSignal>(OnBuildingUpgraded);
_signalBus.Subscribe<RawResourcesRemovedSignal>(OnRawResourcesRemoved);
_signalBus.Subscribe<RoadTileUpdatedSignal>(OnRoadTileUpdated);
_signalBus.Subscribe<BuildMenuButtonUnlockAnimationStartedSignal>(OnBuildMenuButtonUnlockAnimationStarted);
return UniTask.CompletedTask;
}
public void Dispose()
{
_signalBus.Unsubscribe<BuildingPlacementAnimationCompletedSignal>(OnBuildingPlacementAnimationCompleted);
_signalBus.Unsubscribe<ConstructionSiteDeletedSignal>(OnConstructionSiteDeleted);
_signalBus.Unsubscribe<BuildingDeletedSignal>(OnBuildingDeleted);
_signalBus.Unsubscribe<BuildingUpgradedSignal>(OnBuildingUpgraded);
_signalBus.Unsubscribe<RawResourcesRemovedSignal>(OnRawResourcesRemoved);
_signalBus.Unsubscribe<RoadTileUpdatedSignal>(OnRoadTileUpdated);
_signalBus.Unsubscribe<BuildMenuButtonUnlockAnimationStartedSignal>(OnBuildMenuButtonUnlockAnimationStarted);
}
private bool UpdatePlayedTimestamp(int key)
{
var timestamp = _soundPlayedTimestamps.GetValueOrDefault(key);
const float minInterval = 0.1f;
if (Time.unscaledTime - timestamp < minInterval) return false;
_soundPlayedTimestamps[key] = Time.unscaledTime;
return true;
}
private void OnBuildingPlacementAnimationCompleted(BuildingPlacementAnimationCompletedSignal signal)
{
PlaySystemSound(SystemSoundId.BuildingPlaced);
}
private void OnConstructionSiteDeleted(ConstructionSiteDeletedSignal signal)
{
PlaySystemSound(SystemSoundId.BuildingDeleted);
}
private void OnBuildingDeleted(BuildingDeletedSignal signal)
{
if (signal.Options == DeleteBuildingOptions.Silent) return;
PlaySystemSound(SystemSoundId.BuildingDeleted);
}
private void OnBuildingUpgraded(BuildingUpgradedSignal signal)
{
if (!signal.Building.Definition.IsHouse || !UpdatePlayedTimestamp((int)SystemSoundId.HouseUpgraded)) return;
var position = (float3)_tileSpace.GetRectWorldCenter(signal.Building.Rect);
_soundPlayer.PlayAt(SystemSoundId.HouseUpgraded, position);
}
private void OnRawResourcesRemoved(RawResourcesRemovedSignal signal)
{
foreach (var resourceNode in signal.ResourceNodes)
{
var definition = _gameDatabase.WithId<ResourceNodeDefinition>(resourceNode.DefinitionId);
if (!UpdatePlayedTimestamp(definition.RuntimeId)) continue;
if (signal.Reason == RawResourcesRemovedSignal.RemovalReason.Harvested)
_soundPlayer.PlayAt(definition.DeleteAudio, resourceNode.Tile);
else
_soundPlayer.Play(definition.DeleteAudio);
}
}
private void OnRoadTileUpdated(RoadTileUpdatedSignal signal)
{
PlaySystemSound(signal.RoadTileAdded ? SystemSoundId.RoadTilePlaced : SystemSoundId.RoadTileDeleted);
}
private void OnBuildMenuButtonUnlockAnimationStarted(BuildMenuButtonUnlockAnimationStartedSignal signal)
{
PlaySystemSound(SystemSoundId.UnlockNotification);
}
private void PlaySystemSound(SystemSoundId soundId)
{
if (UpdatePlayedTimestamp((int)soundId)) _soundPlayer.Play(soundId);
}
}
}