From 54f48c9a8ad77c0f71216256fcd189e676993e8d Mon Sep 17 00:00:00 2001 From: SamRelativeDimensions Date: Wed, 16 Nov 2022 13:00:33 +0000 Subject: [PATCH 1/5] Occlusion details for PlayEventAttached. Exposed Occlusion details on the PlayEventAttached blueprint callable function. --- .../Source/FMODStudio/Classes/FMODBlueprintStatics.h | 8 ++++++-- .../FMODStudio/Private/FMODBlueprintStatics.cpp | 11 ++++++++++- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/FMODStudio/Source/FMODStudio/Classes/FMODBlueprintStatics.h b/FMODStudio/Source/FMODStudio/Classes/FMODBlueprintStatics.h index 66b4a842..2564593a 100755 --- a/FMODStudio/Source/FMODStudio/Classes/FMODBlueprintStatics.h +++ b/FMODStudio/Source/FMODStudio/Classes/FMODBlueprintStatics.h @@ -70,12 +70,16 @@ class FMODSTUDIO_API UFMODBlueprintStatics : public UBlueprintFunctionLibrary * @param LocationType - Specifies whether Location is a relative offset or an absolute world position * @param bStopWhenAttachedToDestroyed - Specifies whether the sound should stop playing when the owner of the attach to component is destroyed. * @param bAutoPlay - Start the event automatically. - * @param bAutoDestroy - Automatically destroy the audio component when the sound is stopped. + * @param bAutoDestroy - Automatically destroy the audio component when the sound is stopped. + * @param bEnableOcclusion - Whether to enable occlusion for event. + * @param OcclusionTraceChannel - If occlusion is enabled, which collision channel should be used for determining occlusion. + * @param bUseComplexCollisionForOcclusion - If occlusion is enabled, should the simple or complex collision of objects be used to determine occlusion. */ UFUNCTION(BlueprintCallable, Category = "Audio|FMOD", meta = (AdvancedDisplay = "2", UnsafeDuringActorConstruction = "true", bAutoPlay = "true", bAutoDestroy = "true")) static class UFMODAudioComponent *PlayEventAttached(UFMODEvent *Event, USceneComponent *AttachToComponent, FName AttachPointName, - FVector Location, EAttachLocation::Type LocationType, bool bStopWhenAttachedToDestroyed, bool bAutoPlay, bool bAutoDestroy); + FVector Location, EAttachLocation::Type LocationType, bool bStopWhenAttachedToDestroyed, bool bAutoPlay, bool bAutoDestroy, + bool bEnableOcclusion = false, ECollisionChannel OcclusionTraceChannel = ECollisionChannel::ECC_Visibility, bool bUseComplexCollisionForOcclusion = false); /** Find an asset by name. * @param EventName - The asset name diff --git a/FMODStudio/Source/FMODStudio/Private/FMODBlueprintStatics.cpp b/FMODStudio/Source/FMODStudio/Private/FMODBlueprintStatics.cpp index 9c7bdf1e..0b0310a0 100755 --- a/FMODStudio/Source/FMODStudio/Private/FMODBlueprintStatics.cpp +++ b/FMODStudio/Source/FMODStudio/Private/FMODBlueprintStatics.cpp @@ -59,7 +59,8 @@ FFMODEventInstance UFMODBlueprintStatics::PlayEventAtLocation( } class UFMODAudioComponent *UFMODBlueprintStatics::PlayEventAttached(class UFMODEvent *Event, class USceneComponent *AttachToComponent, - FName AttachPointName, FVector Location, EAttachLocation::Type LocationType, bool bStopWhenAttachedToDestroyed, bool bAutoPlay, bool bAutoDestroy) + FName AttachPointName, FVector Location, EAttachLocation::Type LocationType, bool bStopWhenAttachedToDestroyed, bool bAutoPlay, bool bAutoDestroy, + bool bEnableOcclusion /* = false */, ECollisionChannel OcclusionTraceChannel /* ECollisionChannel:: ECC_Visibility */, bool bUseComplexCollisionForOcclusion /* = false*/) { if (!IFMODStudioModule::Get().UseSound()) { @@ -103,6 +104,14 @@ class UFMODAudioComponent *UFMODBlueprintStatics::PlayEventAttached(class UFMODE #if WITH_EDITORONLY_DATA AudioComponent->bVisualizeComponent = false; #endif + + // Create and apply Occlusion details. + FFMODOcclusionDetails OcclusionDetails = FFMODOcclusionDetails(); + OcclusionDetails.bEnableOcclusion = bEnableOcclusion; + OcclusionDetails.bUseComplexCollisionForOcclusion = bUseComplexCollisionForOcclusion; + OcclusionDetails.OcclusionTraceChannel = OcclusionTraceChannel; + AudioComponent->OcclusionDetails = OcclusionDetails; + AudioComponent->RegisterComponentWithWorld(AttachToComponent->GetWorld()); AudioComponent->AttachToComponent(AttachToComponent, FAttachmentTransformRules::KeepRelativeTransform, AttachPointName); From 126bd8dae19264740f2f34751abd0e31385e8212 Mon Sep 17 00:00:00 2001 From: SamRelativeDimensions Date: Wed, 16 Nov 2022 14:05:16 +0000 Subject: [PATCH 2/5] Added Listener Attenuation as a separate transform to be passed through to FMOD Listener Attenuation is now set by default to the Player Controller "Controlled Pawn" PawnViewPoint. This is overrideable on pawns. For example in a third person game, you might want the panning to be at the camera location, but the attenuation to be from the character's head location, meaning that a world sound doesn't get louder and quieter just from orbiting the camera around the controlled pawn. --- .../FMODStudio/Private/FMODStudioModule.cpp | 19 +++++++++++++++---- .../FMODStudio/Public/FMODStudioModule.h | 2 +- .../Private/FMODStudioEditorModule.cpp | 2 +- 3 files changed, 17 insertions(+), 6 deletions(-) diff --git a/FMODStudio/Source/FMODStudio/Private/FMODStudioModule.cpp b/FMODStudio/Source/FMODStudio/Private/FMODStudioModule.cpp index 6be102ca..14ded11e 100755 --- a/FMODStudio/Source/FMODStudio/Private/FMODStudioModule.cpp +++ b/FMODStudio/Source/FMODStudio/Private/FMODStudioModule.cpp @@ -212,7 +212,7 @@ class FFMODStudioModule : public IFMODStudioModule virtual FMOD::Studio::EventInstance *CreateAuditioningInstance(const UFMODEvent *Event) override; virtual void StopAuditioningInstance() override; - virtual void SetListenerPosition(int ListenerIndex, UWorld *World, const FTransform &ListenerTransform, float DeltaSeconds) override; + virtual void SetListenerPosition(int ListenerIndex, UWorld *World, const FTransform &ListenerTransform, const FTransform &listenerAttenuationTransform, float DeltaSeconds) override; virtual void FinishSetListenerPosition(int ListenerCount) override; virtual const FFMODListener &GetNearestListener(const FVector &Location) override; @@ -934,7 +934,15 @@ void FFMODStudioModule::UpdateWorldListeners(UWorld *World, int *ListenerIndex) ListenerTransform.SetTranslation(Location); ListenerTransform.NormalizeRotation(); - SetListenerPosition(*ListenerIndex, World, ListenerTransform, DeltaSeconds); + APawn* ControlledPawn = PlayerController->GetPawn(); + FTransform ListenerAttenuationTransform(FTransform::Identity); + if (IsValid(ControlledPawn)) + { + ListenerAttenuationTransform = ControlledPawn->GetActorTransform(); // actor + ListenerAttenuationTransform.SetLocation(ControlledPawn->GetPawnViewLocation()); // head + } + + SetListenerPosition(*ListenerIndex, World, ListenerTransform, ListenerAttenuationTransform, DeltaSeconds); (*ListenerIndex)++; } @@ -971,7 +979,7 @@ const FFMODListener &FFMODStudioModule::GetNearestListener(const FVector &Locati } // Partially copied from FAudioDevice::SetListener -void FFMODStudioModule::SetListenerPosition(int ListenerIndex, UWorld *World, const FTransform &ListenerTransform, float DeltaSeconds) +void FFMODStudioModule::SetListenerPosition(int ListenerIndex, UWorld *World, const FTransform &ListenerTransform, const FTransform &ListenerAttenuationTransform, float DeltaSeconds) { FMOD::Studio::System *System = IFMODStudioModule::Get().GetStudioSystem(EFMODSystemContext::Runtime); if (System && ListenerIndex < MAX_LISTENERS) @@ -1009,7 +1017,10 @@ void FFMODStudioModule::SetListenerPosition(int ListenerIndex, UWorld *World, co Attributes.forward = FMODUtils::ConvertUnitVector(Forward); Attributes.up = FMODUtils::ConvertUnitVector(Up); Attributes.velocity = FMODUtils::ConvertWorldVector(Listeners[ListenerIndex].Velocity); - verifyfmod(System->setListenerAttributes(ListenerIndex, &Attributes)); + + FMOD_VECTOR AttenuationLocation = FMODUtils::ConvertWorldVector(ListenerAttenuationTransform.GetTranslation()); + + verifyfmod(System->setListenerAttributes(ListenerIndex, &Attributes, &AttenuationLocation)); bListenerMoved = true; } } diff --git a/FMODStudio/Source/FMODStudio/Public/FMODStudioModule.h b/FMODStudio/Source/FMODStudio/Public/FMODStudioModule.h index 7cb60f3a..9a609c6a 100755 --- a/FMODStudio/Source/FMODStudio/Public/FMODStudioModule.h +++ b/FMODStudio/Source/FMODStudio/Public/FMODStudioModule.h @@ -127,7 +127,7 @@ class IFMODStudioModule : public IModuleInterface /** * Called to change the listener position for editor mode */ - virtual void SetListenerPosition(int ListenerIndex, UWorld *World, const FTransform &ListenerTransform, float DeltaSeconds) = 0; + virtual void SetListenerPosition(int ListenerIndex, UWorld *World, const FTransform &ListenerTransform, const FTransform& ListenerAttenuationTransform, float DeltaSeconds) = 0; /** * Called to change the listener position for editor mode diff --git a/FMODStudio/Source/FMODStudioEditor/Private/FMODStudioEditorModule.cpp b/FMODStudio/Source/FMODStudioEditor/Private/FMODStudioEditorModule.cpp index e366d514..b71464ba 100755 --- a/FMODStudio/Source/FMODStudioEditor/Private/FMODStudioEditorModule.cpp +++ b/FMODStudio/Source/FMODStudioEditor/Private/FMODStudioEditorModule.cpp @@ -1157,7 +1157,7 @@ void FFMODStudioEditorModule::ViewportDraw(UCanvas *Canvas, APlayerController *) ListenerTransform.SetTranslation(ViewLocation); ListenerTransform.NormalizeRotation(); - IFMODStudioModule::Get().SetListenerPosition(0, World, ListenerTransform, 0.0f); + IFMODStudioModule::Get().SetListenerPosition(0, World, ListenerTransform, FTransform::Identity, 0.0f); IFMODStudioModule::Get().FinishSetListenerPosition(1); } } From d5dd16705c2f9d05019e5b48d108c90cab2b9691 Mon Sep 17 00:00:00 2001 From: SamRelativeDimensions Date: Wed, 16 Nov 2022 14:08:31 +0000 Subject: [PATCH 3/5] Changed FMODAudioComponent.h access specifiers for ActorComponent interface to allow for virtual overrides. Changed FMODAudioComponent.h access specifiers for ActorComponent interface from private to protected to allow for virtual overrides. --- FMODStudio/Source/FMODStudio/Classes/FMODAudioComponent.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/FMODStudio/Source/FMODStudio/Classes/FMODAudioComponent.h b/FMODStudio/Source/FMODStudio/Classes/FMODAudioComponent.h index dcf2c4ff..d658ebf3 100755 --- a/FMODStudio/Source/FMODStudio/Classes/FMODAudioComponent.h +++ b/FMODStudio/Source/FMODStudio/Classes/FMODAudioComponent.h @@ -326,6 +326,7 @@ class FMODSTUDIO_API UFMODAudioComponent : public USceneComponent /** Called when the event has finished stopping. */ void OnPlaybackCompleted(); +protected: // Begin ActorComponent interface. /** Called when a component is registered, after Scene is set, but before CreateRenderState_Concurrent or OnCreatePhysicsState are called. */ virtual void OnRegister() override; @@ -340,6 +341,8 @@ class FMODSTUDIO_API UFMODAudioComponent : public USceneComponent virtual void TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction *ThisTickFunction) override; // End ActorComponent interface. +private: + #if WITH_EDITORONLY_DATA void UpdateSpriteTexture(); #endif From 42bf2b8834e5b3b47471f79419ea827e1a84e929 Mon Sep 17 00:00:00 2001 From: SamRelativeDimensions Date: Wed, 16 Nov 2022 14:17:27 +0000 Subject: [PATCH 4/5] Allow Editor Viewport camera position to update listener position when simulating in editor. By default, FMOD doesn't allow for flying around in editor to hear the world sounds. This change allows for the editor viewport position to be used as the world listener position during UpdateListeners so that audio designers can fly around their worlds in simulation to hear things properly. --- .../Source/FMODStudio/Private/FMODStudioModule.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/FMODStudio/Source/FMODStudio/Private/FMODStudioModule.cpp b/FMODStudio/Source/FMODStudio/Private/FMODStudioModule.cpp index 14ded11e..3d6a8dae 100755 --- a/FMODStudio/Source/FMODStudio/Private/FMODStudioModule.cpp +++ b/FMODStudio/Source/FMODStudio/Private/FMODStudioModule.cpp @@ -41,6 +41,10 @@ #include #endif +#if WITH_EDITOR +#include "LevelEditorViewport.h" +#endif + #define LOCTEXT_NAMESPACE "FMODStudio" DEFINE_LOG_CATEGORY(LogFMOD); @@ -876,6 +880,11 @@ void FFMODStudioModule::UpdateListeners() #if WITH_EDITOR if (bSimulating) { + if (GEngine && GEngine->GameViewport) + { + UpdateWorldListeners(GEngine->GameViewport->GetWorld(), &ListenerIndex); + } + return; } From 4c83d0a535feb18d5208f6fc6bcf52b0f283df98 Mon Sep 17 00:00:00 2001 From: SamRelativeDimensions Date: Wed, 16 Nov 2022 14:21:36 +0000 Subject: [PATCH 5/5] Only active viewport during simulation acts as audio listener transform. In addition to a previous CL for allowing audio in viewports during "simulation". This CL ensures that only the active viewport (if multiple are open) during simulation updates the listener Transform. --- .../FMODStudio/Private/FMODStudioModule.cpp | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/FMODStudio/Source/FMODStudio/Private/FMODStudioModule.cpp b/FMODStudio/Source/FMODStudio/Private/FMODStudioModule.cpp index 3d6a8dae..8357df28 100755 --- a/FMODStudio/Source/FMODStudio/Private/FMODStudioModule.cpp +++ b/FMODStudio/Source/FMODStudio/Private/FMODStudioModule.cpp @@ -951,6 +951,23 @@ void FFMODStudioModule::UpdateWorldListeners(UWorld *World, int *ListenerIndex) ListenerAttenuationTransform.SetLocation(ControlledPawn->GetPawnViewLocation()); // head } +#if WITH_EDITOR + if (bSimulating) + { + for (FLevelEditorViewportClient* LevelVC : GEditor->GetLevelViewportClients()) + { + if (LevelVC && LevelVC->IsPerspective()) + { + ListenerTransform.SetLocation(LevelVC->GetViewLocation()); + ListenerTransform.SetRotation(LevelVC->GetViewRotation().Quaternion()); + break; + } + } + + ListenerAttenuationTransform = ListenerTransform; + } +#endif + SetListenerPosition(*ListenerIndex, World, ListenerTransform, ListenerAttenuationTransform, DeltaSeconds); (*ListenerIndex)++;