Audio Ears on the Character, not the Camera?

We are working on a third person shooter project and the camera is a few feet behind the character so he is well in view. When dialing in audio attenuation I noticed that the “ears” of the player are on the camera and not the character in front of you, so attenuated sounds can be noticeably louder when facing away from them. I get it, makes sense as a spectator with a camera, but not great for spatial awareness while imagining you are the Character - not watching twelve feet behind him.

I researched/googled all sorts of docs/links and found nothing on changing this default setup. Is there a way to put the “ears” of the player on the character/capsule, not the camera?

Sorry if a simple question, I am a seasoned animator but a total newb in UE4 programming. Any info or a doc you can point me to would be awesome.

Thanks in advance,
Cris

2 Likes

Much digging, different search terms, finally found it.

Set Audio Listener Override

Looking at how to connect it in the PlayerController now.

2 Likes

I made a tutorial about it. I hope it’s gonna be usefull.

6 Likes

Thanks! Nice tutorial. I was using the first simple method and rotating it 90 degrees in the override node to face it the correct direction, but this looks like fixes other things as well.

My only real issue now is that it is multiplayer, and I’m not sure how to replicate it for all clients without causing other problems. As is, everyone hears the “ears” of the last player that spawns. Another player joins or respawns, now everyone hears those new ears.
Something on BeginPlay needs to iterate only to the new spawned player and not override all existing Server and client players audio.

There is a much easier and more organic way to achieve this without doing anything on tick or hacking together rotations, for future googlers (I know, its an old thread). Override APlayerController::GetAudioListenerPosition() and add:


if (GetPawn())
{
    ViewLocation = GetPawn()->GetActorLocation();
}

In the else statement under GetPlayerViewPoint(ViewLocation, ViewRotation), here’s the full function. The result is that it uses the pawn’s location but the camera’s rotation.


FVector ViewLocation;
FRotator ViewRotation;

if (bOverrideAudioListener)
{
    USceneComponent* ListenerComponent = AudioListenerComponent.Get();
    if (ListenerComponent != nullptr)
    {
        ViewRotation = ListenerComponent->GetComponentRotation() + AudioListenerRotationOverride;
        ViewLocation = ListenerComponent->GetComponentLocation() + ViewRotation.RotateVector(AudioListenerLocationOverride);
    }
    else
    {
        ViewLocation = AudioListenerLocationOverride;
        ViewRotation = AudioListenerRotationOverride;
    }
}
else
{
    GetPlayerViewPoint(ViewLocation, ViewRotation);
    if (GetPawn())
    {
        ViewLocation = GetPawn()->GetActorLocation();
    }
}

const FRotationTranslationMatrix ViewRotationMatrix(ViewRotation, ViewLocation);

OutLocation = ViewLocation;
OutFrontDir = ViewRotationMatrix.GetUnitAxis(EAxis::X);
OutRightDir = ViewRotationMatrix.GetUnitAxis(EAxis::Y);

5 Likes

This worked great! Just a note to inlclude the entire signature when overriding: YourPlayerController::GetAudioListenerPosition(FVector& OutLocation, FVector& OutFrontDir, FVector& OutRightDir)

1 Like

Nice! It worked so well!
Guys, don’t forget to create your own APlayerController CPP and put

-In the .h file:
virtual void GetAudioListenerPosition(FVector& OutLocation, FVector& OutFrontDir, FVector& OutRightDir) const override;
-In the .cpp file:
void ABasePlayerController::GetAudioListenerPosition(FVector& OutLocation, FVector& OutFrontDir, FVector& OutRightDir) const
{
Super::GetAudioListenerPosition(OutLocation, OutFrontDir, OutRightDir);
Copy and paste the entire code form 's post
}

In the GameMode BP set your custom PlayerController CPP as default Player Controller (In my case ABasePlayerController), and you are good to go!

1 Like

In 4.24.3 the declarations have to be without the const, so

in the .h:

virtual void GetAudioListenerPosition(FVector& OutLocation, FVector& OutFrontDir, FVector& OutRightDir);

and in the cpp:

void APlaneshiftPlayerControllerBase::GetAudioListenerPosition(FVector& OutLocation, FVector& OutFrontDir, FVector& OutRightDir)

The line:

Super::GetAudioListenerPosition(OutLocation, OutFrontDir, OutRightDir);

to me its unecessary as it will just execute the same code in the super class APlayerController. I removed it and it works anyway.

1 Like

Hi !

Could you or some other user “translate” this code in Blueprint? Screenshots or a simple schematic explanation is OK.

I don’t want to use the tick event for this, so your solution should be better but my knowledge of C++ is limited.

Edit: This is now exposed to blueprint

It’s C++ only. Also now in GetAudioListenerPosition instead of GetPlayerViewPoint

1 Like

For future googlers like me, there is a simple solution for BLUEPRINTS! Just add node “Set Audio Listener Override” into your Player Controller BP and attach it to your character (I attached this to capsule component). Note, I am building multiplayer so I am executing the node when it “Is Local Player Controller” only.

5 Likes

Firstly I want to thank @Bartosz_Kamol_Kaminski for their excellent tutorial as well as DK Buzzin’s YouTube comment. I modified the solution slightly to have the setup in the Player Controller itself, and it can apply to any player controlled pawn or character.
Simply drag off of Begin Play in your Player Controller, and search for “Set Audio Listener Attenuation Override”. Then Get Player Pawn, drag out of that and get the Root Component then plug into “Attach to Component” input. It works great! :grin:

3 Likes

Your timing to post this couldn’t have been better as I just wanted to get this to work.
This method works an absolute charm. Thanks a lot!

1 Like

This tutorial is great! I read in the comments you can also use the SetAudioListenerAttenuationOverride node to achieve the same thing without the offset math. Thank you so much!
image

1 Like

You’re welcome! Glad it helped! :grinning:

Thank you so much! My camera is 8000 units away from the player. I was wondering why the attenuation was not working. Now it works perfectly!

1 Like