Add weather audio cues
This commit is contained in:
@@ -0,0 +1,149 @@
|
||||
// Copyright Pacificao. All Rights Reserved.
|
||||
|
||||
#include "AgrarianWeatherAudioController.h"
|
||||
|
||||
#include "AgrarianGameState.h"
|
||||
#include "Components/AudioComponent.h"
|
||||
#include "Components/SceneComponent.h"
|
||||
#include "Engine/World.h"
|
||||
|
||||
AAgrarianWeatherAudioController::AAgrarianWeatherAudioController()
|
||||
{
|
||||
PrimaryActorTick.bCanEverTick = true;
|
||||
bReplicates = false;
|
||||
|
||||
SceneRoot = CreateDefaultSubobject<USceneComponent>(TEXT("SceneRoot"));
|
||||
RootComponent = SceneRoot;
|
||||
|
||||
AmbientAudio = CreateDefaultSubobject<UAudioComponent>(TEXT("AmbientAudio"));
|
||||
AmbientAudio->SetupAttachment(SceneRoot);
|
||||
AmbientAudio->bAutoActivate = false;
|
||||
|
||||
RainAudio = CreateDefaultSubobject<UAudioComponent>(TEXT("RainAudio"));
|
||||
RainAudio->SetupAttachment(SceneRoot);
|
||||
RainAudio->bAutoActivate = false;
|
||||
|
||||
WindAudio = CreateDefaultSubobject<UAudioComponent>(TEXT("WindAudio"));
|
||||
WindAudio->SetupAttachment(SceneRoot);
|
||||
WindAudio->bAutoActivate = false;
|
||||
|
||||
StormAudio = CreateDefaultSubobject<UAudioComponent>(TEXT("StormAudio"));
|
||||
StormAudio->SetupAttachment(SceneRoot);
|
||||
StormAudio->bAutoActivate = false;
|
||||
}
|
||||
|
||||
void AAgrarianWeatherAudioController::BeginPlay()
|
||||
{
|
||||
Super::BeginPlay();
|
||||
AssignConfiguredSounds();
|
||||
RefreshWeatherAudio(0.0f);
|
||||
}
|
||||
|
||||
void AAgrarianWeatherAudioController::Tick(float DeltaSeconds)
|
||||
{
|
||||
Super::Tick(DeltaSeconds);
|
||||
RefreshWeatherAudio(DeltaSeconds);
|
||||
}
|
||||
|
||||
void AAgrarianWeatherAudioController::RefreshWeatherAudio(float DeltaSeconds)
|
||||
{
|
||||
const UWorld* World = GetWorld();
|
||||
const AAgrarianGameState* GameState = World ? World->GetGameState<AAgrarianGameState>() : nullptr;
|
||||
if (!GameState)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
CurrentWeather = GameState->Weather;
|
||||
const float WindAlpha = GetProviderWindAlpha(GameState->ActiveWeatherInputs.WindSpeedKmh, GameState->ActiveWeatherInputs.bHasProviderData);
|
||||
float TargetRainVolume = 0.0f;
|
||||
float TargetWindVolume = WindAlpha * MaxWindVolume;
|
||||
float TargetStormVolume = 0.0f;
|
||||
|
||||
switch (GameState->Weather)
|
||||
{
|
||||
case EAgrarianWeatherType::Rain:
|
||||
TargetRainVolume = MaxRainVolume;
|
||||
TargetWindVolume = FMath::Max(TargetWindVolume, MaxWindVolume * 0.25f);
|
||||
break;
|
||||
case EAgrarianWeatherType::ColdWind:
|
||||
TargetWindVolume = FMath::Max(TargetWindVolume, MaxWindVolume * 0.7f);
|
||||
break;
|
||||
case EAgrarianWeatherType::Storm:
|
||||
TargetRainVolume = MaxRainVolume;
|
||||
TargetWindVolume = MaxWindVolume;
|
||||
TargetStormVolume = MaxStormVolume;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
const float TargetAmbientVolume = GameState->IsNight() ? AmbientNightVolume : AmbientDayVolume;
|
||||
const float InterpSpeed = FMath::Max(0.1f, VolumeInterpSpeed);
|
||||
CurrentAmbientVolume = FMath::FInterpTo(CurrentAmbientVolume, TargetAmbientVolume, DeltaSeconds, InterpSpeed);
|
||||
CurrentRainVolume = FMath::FInterpTo(CurrentRainVolume, TargetRainVolume, DeltaSeconds, InterpSpeed);
|
||||
CurrentWindVolume = FMath::FInterpTo(CurrentWindVolume, TargetWindVolume, DeltaSeconds, InterpSpeed);
|
||||
CurrentStormVolume = FMath::FInterpTo(CurrentStormVolume, TargetStormVolume, DeltaSeconds, InterpSpeed);
|
||||
|
||||
if (DeltaSeconds <= 0.0f)
|
||||
{
|
||||
CurrentAmbientVolume = TargetAmbientVolume;
|
||||
CurrentRainVolume = TargetRainVolume;
|
||||
CurrentWindVolume = TargetWindVolume;
|
||||
CurrentStormVolume = TargetStormVolume;
|
||||
}
|
||||
|
||||
ApplyComponentVolume(AmbientAudio, CurrentAmbientVolume);
|
||||
ApplyComponentVolume(RainAudio, CurrentRainVolume);
|
||||
ApplyComponentVolume(WindAudio, CurrentWindVolume);
|
||||
ApplyComponentVolume(StormAudio, CurrentStormVolume);
|
||||
}
|
||||
|
||||
void AAgrarianWeatherAudioController::AssignConfiguredSounds()
|
||||
{
|
||||
if (AmbientAudio && ClearAmbientSound)
|
||||
{
|
||||
AmbientAudio->SetSound(ClearAmbientSound);
|
||||
}
|
||||
if (RainAudio && RainLoopSound)
|
||||
{
|
||||
RainAudio->SetSound(RainLoopSound);
|
||||
}
|
||||
if (WindAudio && WindLoopSound)
|
||||
{
|
||||
WindAudio->SetSound(WindLoopSound);
|
||||
}
|
||||
if (StormAudio && StormLoopSound)
|
||||
{
|
||||
StormAudio->SetSound(StormLoopSound);
|
||||
}
|
||||
}
|
||||
|
||||
void AAgrarianWeatherAudioController::ApplyComponentVolume(UAudioComponent* AudioComponent, float Volume) const
|
||||
{
|
||||
if (!AudioComponent)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const float SafeVolume = FMath::Clamp(Volume, 0.0f, 1.0f);
|
||||
AudioComponent->SetVolumeMultiplier(SafeVolume);
|
||||
if (AudioComponent->Sound && SafeVolume > 0.01f && !AudioComponent->IsPlaying())
|
||||
{
|
||||
AudioComponent->Play();
|
||||
}
|
||||
else if (SafeVolume <= 0.01f && AudioComponent->IsPlaying())
|
||||
{
|
||||
AudioComponent->Stop();
|
||||
}
|
||||
}
|
||||
|
||||
float AAgrarianWeatherAudioController::GetProviderWindAlpha(float WindSpeedKmh, bool bHasProviderData) const
|
||||
{
|
||||
if (!bHasProviderData)
|
||||
{
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
return FMath::Clamp(WindSpeedKmh / 55.0f, 0.0f, 1.0f);
|
||||
}
|
||||
Reference in New Issue
Block a user