Game.SFXCullingSystem
Assembly: Assembly-CSharp
Namespace: Game.Audio
Type: class
Base: GameSystemBase
Summary:
SFXCullingSystem is an ECS system responsible for culling and updating audio sources (SFX) for prefabs based on camera distance, culling groups and per-effect rules. The system uses Burst-compiled Jobs to evaluate enabled effects, enqueue items into culling group queues, and optionally performs group-level culling to limit the number of active audio sources per group. It interacts with AudioManager (for source updates), EffectControlSystem (for the enabled effects buffer), and an optional CullingAudioSettingsData singleton to control group culling limits. The system contains several nested types: SFXCullingJob, SFXGroupCullingJob, CullingGroupItem and a TypeHandle helper for Component/Buffer lookups. The class is set up to run in Unity's DOTS/ECS environment and uses Native containers and job dependencies to schedule work safely.
Fields
-
private AudioManager m_AudioManager
Handles audio source updates and provides SourceUpdateData used to add/remove audio sources that should be played or stopped. Initialized in OnCreate by fetching/creating the managed AudioManager system. -
private EffectControlSystem m_EffectControlSystem
Provides access to the enabled effects NativeList used by the culling job. Initialized in OnCreate by fetching/creating the managed EffectControlSystem. -
private EntityQuery m_CullingAudioSettingsQuery
EntityQuery used to check for and read the optional CullingAudioSettingsData singleton which configures group culling limits and distances. -
private TypeHandle __TypeHandle
Helper struct that stores ComponentLookup/BufferLookup handles for all required component and buffer types (PrefabRef, CullingGroupData, AudioSpotData, AudioEffectData, AudioSourceData, Effect). These are assigned in OnCreateForCompiler via __AssignHandles. -
(Nested types)
SFXCullingJob
,SFXGroupCullingJob
,CullingGroupItem
,TypeHandle
Defined inside the system. SFXCullingJob (Burst compiled) iterates enabled effects and decides per-effect whether to add/remove/update audio sources or enqueue items for group culling. SFXGroupCullingJob (Burst compiled) processes culling-group queues, sorts by distance, and enforces per-group limits / distance thresholds.
Properties
- This class does not expose public properties. All working state is stored in private fields and the system interacts via ECS jobs and other systems (AudioManager, EffectControlSystem).
Constructors
public SFXCullingSystem()
Parameterless constructor. Marked with [Preserve] attribute on lifecycle methods to avoid stripping. The system relies on ECS lifecycle callbacks (OnCreate / OnUpdate) for initialization and runtime behavior.
Methods
-
[Preserve] protected override void OnCreate()
Initializes internal references: obtains the AudioManager and EffectControlSystem managed systems and creates the EntityQuery for CullingAudioSettingsData. This prepares the system to fetch enabled effect data and to publish SourceUpdateData requests to the AudioManager. -
[Preserve] protected override void OnUpdate()
Primary runtime logic. Steps performed: - Skips work if Camera.main is null.
- Creates a NativeParallelQueue
to collect per-group candidate items (size = number of groups). - Requests the enabled effects NativeList from EffectControlSystem and the SourceUpdateData writer from AudioManager (both return JobHandles for dependency chaining).
- Builds and schedules a Burst-compiled SFXCullingJob (IJobParallelForDefer) which:
- Iterates enabled effects, checks flags (IsAudio, IsEnabled, WrongPrefab, EditorContainer),
- Uses ComponentLookup/BufferLookup to read prefab data (CullingGroupData, AudioSpotData, AudioEffectData, AudioSourceData, Effect),
- Computes distance (or closest source point) to camera, enqueues group items if the prefab has a culling group, handles enabling/disabling sources and interval timing for audio spots.
- If a CullingAudioSettingsData singleton exists, schedules a SFXGroupCullingJob (IJobParallelFor) that:
- Reads per-group items from the native queue, sorts them by distance, enforces max allowed amount and max distance, adds/removes source updates accordingly and marks effects with AudioDisabled flag where needed.
- Properly chains JobHandles, disposes nativeParallelQueue on job completion, and registers writers with EffectControlSystem and AudioManager to merge dependencies.
The method uses InternalCompilerInterface helper calls to convert stored lookup handles to runtime ComponentLookup/BufferLookup instances with the current state.
-
private void __AssignQueries(ref SystemState state)
Compiler helper to assign any EntityQuery(s) at compile-time. In the decompiled source it creates a blank EntityQueryBuilder and disposes it; actual queries are created/used elsewhere. -
protected override void OnCreateForCompiler()
Compiler-time creation helper: calls __AssignQueries and assigns Component/Buffer lookups on the saved TypeHandle. Ensures that the TypeHandle is properly initialized for use when jobs run. -
[MethodImpl(MethodImplOptions.AggressiveInlining)]
and[BurstCompile]
usage notes: - SFXCullingJob and SFXGroupCullingJob are Burst-compiled to maximize performance. The system uses aggressive inlining for TypeHandle assignments to reduce overhead when creating Component/Buffer lookup handles.
Usage Example
// The SFXCullingSystem is created and updated by the ECS world automatically.
// To influence group culling behavior, add or modify the CullingAudioSettingsData singleton:
var world = World.DefaultGameObjectInjectionWorld;
var em = world.EntityManager;
// Create or find a singleton entity and set culling settings:
Entity settingsEntity;
if (!em.HasComponent<CullingAudioSettingsData>(/* your singleton entity or use CreateEntity */ Entity.Null))
{
settingsEntity = em.CreateEntity(typeof(CullingAudioSettingsData));
}
else
{
// obtain the existing singleton entity according to your project's singleton pattern
settingsEntity = /* your code to find the singleton entity */;
}
// Configure group culling: max 8 public-trans sounds per group, max distance 500 units
em.SetComponentData(settingsEntity, new CullingAudioSettingsData
{
m_PublicTransCullMaxAmount = 8,
m_PublicTransCullMaxDistance = 500f
});
// You can also get the system instance (read-only) if you need to query or debug it:
var sfxCulling = world.GetExistingSystemManaged<Game.Audio.SFXCullingSystem>();
Notes:
- The SFXCullingSystem is designed to run in a DOTS/ECS environment and relies on internal component/buffer types (PrefabRef, CullingGroupData, AudioSpotData, AudioEffectData, AudioSourceData, Effect, EnabledEffectData, etc.). Modifications must respect thread-safety and job dependency patterns.
- Be careful when interacting directly with the internal NativeList