Hello,
We’re experiencing sounds losing MetaSound parameter updates after returning from virtualization. Affected sounds perform spatialization, attenuation (per-layer) and occlusion (custom plugin) inside the
MetaSound and are looping (OneShot interface disabled). The audible result is “stuck” vehicle sounds playing at MetaSound parameter defaults — RPM, gear state, etc. — until the sound re-enters and exits the
virtualization radius again. A separate attenuation asset handling the overall range continues to work correctly throughout.
We have a custom audio component pooling system. The stuck audio is confirmed to occur only on pooled components. Disabling audio component pooling eliminates the issue entirely.
Acquire flow
When no free component exists, we call NewObject<UAudioComponent>(this) (owner is a UGameInstanceSubsystem). Whether the component comes from the pool or is newly created, it goes through an identical init
path:
-bAutoActivate = false; bStopWhenOwnerDestroyed = false;
-SetWorldLocation(from SourceObject);
-AudioDeviceID = world audio device;
-RegisterComponentWithWorld(ContextWorld); // required — omitting breaks spatialization even without pooling
-InitializeComponent();
-BeginPlay();
Components are only returned to the pool in two cases: the sound finishes/is stopped, or the owning context is destroyed. A virtualizing sound is never returned to the pool — the component stays active
throughout virtualization.
Release/reset flow
Audio subsystem pre-release:
- Broadcast OnAudioComponentPreDestroyed
- Unbind OnAudioFinishedDelegateHandle
- Stop() / DetachFromComponent(KeepWorld)
Pooling subsystem (ReleaseComponent):
- Rename outer to subsystem
- EndPlay(RemovedFromWorld)
- UninitializeComponent()
- DetachFromComponent (shared scene component path)
- UnregisterComponent()
- SetComponentTickEnabled(false)
Reset specialization (AudioComponentPoolingSpecialization::ResetObject):
- If ActiveCount > 0: binds OnAudioFinishedNative async callback, calls Stop() if still active, returns RequiresAsync — component stays in pending reset until the audio thread clears
- Once clear: SetSound(nullptr), clears attenuation, concurrency, source effects, low-pass filter, parameters, volume, component tags, and all native delegates (OnAudioFinished, play state, virtualization,
playback percent, envelope)
The fix at runtime is setting the master bus volume to 0 and back — which flushes the audio system and unsticks the sounds. The problem occurs most reliably in larger playtests (50+ players) but reproduces
occasionally at smaller scale. Reproduction is inconsistent given the number of concurrent actions.
1. Is there anything missing from the reset flow above that could cause a recycled UAudioComponent to lose its MetaSound parameter connection after RegisterComponentWithWorld / InitializeComponent /
BeginPlay are re-called on re-acquisition?
2. Could UnregisterComponent + RegisterComponentWithWorld on a recycled component leave the component in a state where the audio thread no longer routes position/parameter updates to its active sound,
specifically after that sound returns from virtualization?
3. Is there a known issue with pooled UAudioComponent instances and MetaSound parameter updates post-virtualization?
Any guidance on what to verify or instrument would be appreciated.
We made a [related [Content removed] a while back, but had temporarily disabled this work due to the ongoing issue.
Cheers,
Mathias
[Attachment Removed]