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 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); diff --git a/FMODStudio/Source/FMODStudio/Private/FMODStudioModule.cpp b/FMODStudio/Source/FMODStudio/Private/FMODStudioModule.cpp index 6be102ca..8357df28 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); @@ -212,7 +216,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; @@ -876,6 +880,11 @@ void FFMODStudioModule::UpdateListeners() #if WITH_EDITOR if (bSimulating) { + if (GEngine && GEngine->GameViewport) + { + UpdateWorldListeners(GEngine->GameViewport->GetWorld(), &ListenerIndex); + } + return; } @@ -934,7 +943,32 @@ 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 + } + +#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)++; } @@ -971,7 +1005,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 +1043,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); } }