So, we are making a third person game. As you may know, by default audio is picked up by the cameras position. I have implemented the solution from Bartosz Kamiński’s video (see below), as well as by just attaching “Set Audio Listener Attenuation Override” to begin play.
They both have problems though. The main reason I am trying to achieve this, is because when the player runs into an audio volume, if the camera has not yet entered that volume, you can’t hear any of the sounds coming off of the player (footsteps vocals, etc). So I want volume attenuation picked up from the player, while spatialazation is picked up from the camera. The first solution fixes this, but it is not without its bugs. First off, it would seem as though tick is not fast enough as rotating the player mesh rapidly will still cause some artifacts with spatialization. Second, there are concerns from my team that this is not good for optimization, as you are constantly reattaching the listener. The second solution, you would think would be perfect, but for some reason, it does not fix the problem of audio volumes at all. It will make sounds louder and quieter from the meshes position, but if you walk into an audio volume and the camera is outside, you can’t hear anything coming off the player. Does anyone know of a better fix for this?
Hi! You can use this snippet to customize almost everything in Sound params… However, it has some cons if you want to use it with cancelable sounds… But for uncancelable things rather useful…
void PlayWithCustomParams(USoundBase* Sound, FPlaySFXContext& context, FVector location) {
if (auto world = /*Get the UWorld* from something...*/) {
if (auto AudioDevice = world->GetAudioDevice()) {
if (CanPlaySound(Sound, world)) { // Any check that you need
const FSoundAttenuationSettings* AttenuationSettingsToApply = (Sound->GetAttenuationSettingsToApply());
float MaxDistance = 0.0f;
float FocusFactor = 1.0f;
AudioDevice->GetMaxDistanceAndFocusFactor(Sound, world, location, AttenuationSettingsToApply, MaxDistance, FocusFactor);
if (Sound->IsLooping() || Sound->IsPlayWhenSilent() ||
AudioDevice->SoundIsAudible(Sound, world, location, AttenuationSettingsToApply, MaxDistance, FocusFactor)) {
const bool bIsInGameWorld = world->IsGameWorld();
FActiveSound NewActiveSound;
NewActiveSound.SetWorld(world);
NewActiveSound.SetSound(Sound);
NewActiveSound.SetVolume(context.VolumeMultiplier);
NewActiveSound.SetPitch(context.PitchMultiplier);
NewActiveSound.RequestedStartTime = FMath::Max(0.0f, context.StartTime);
NewActiveSound.bLocationDefined = true;
NewActiveSound.Transform.SetTranslation(location);
NewActiveSound.Transform.SetRotation(FQuat(FRotator::ZeroRotator));
NewActiveSound.bIsUISound = !bIsInGameWorld;
NewActiveSound.SubtitlePriority = Sound->GetSubtitlePriority();
NewActiveSound.bHasAttenuationSettings = AttenuationSettingsToApply != nullptr;
if (NewActiveSound.bHasAttenuationSettings) {
const FGlobalFocusSettings& FocusSettings = AudioDevice->GetGlobalFocusSettings();
NewActiveSound.AttenuationSettings = *AttenuationSettingsToApply;
NewActiveSound.FocusData.PriorityScale = AttenuationSettingsToApply->GetFocusPriorityScale(FocusSettings, FocusFactor);
NewActiveSound.FocusData.DistanceScale = AttenuationSettingsToApply->GetFocusDistanceScale(FocusSettings, FocusFactor);
}
NewActiveSound.MaxDistance = MaxDistance;
////// TODO ConcurrencySettings
//////if (Concurrency) {
////// NewActiveSound.ConcurrencySet.Add(Concurrency);
//////}
NewActiveSound.Priority = Sound->Priority;
NewActiveSound.SetOwner(nullptr);
AudioDevice->AddNewActiveSound(NewActiveSound);
}
else {
// Don't play a sound for short sounds that start out of range of any listener
UE_LOG(LogAudio, Log, TEXT("Sound not played for out of range Sound %s"), *Sound->GetName());
}
}
}
}
}