Game.Effects.SearchSystem
Assembly: Game
Namespace: Game.Effects
Type: class
Base: GameSystemBase, IPreDeserialize
Summary:
SearchSystem maintains a spatial search structure (a NativeQuadTree) of active effect sources (light, audio, particle, etc.) and keeps that structure in sync with entity/component changes. It schedules a Burst-compiled IJobChunk (UpdateSearchTreeJob) to scan relevant entities and add/remove/update source bounds in the quad tree. The system coordinates effect enable/disable logic via EffectControlData and synchronizes read/write access to the quad tree through JobHandle-based reader/writer bookkeeping. PreDeserialize clears the tree and prepares it for reloads.
Fields
-
private EffectFlagSystem m_EffectFlagSystem
Stores a reference to the EffectFlagSystem used to query effect flags and state needed when determining whether effects should be enabled. -
private SimulationSystem m_SimulationSystem
Reference to the SimulationSystem (used for frame index and simulation state relevant when evaluating effect control). -
private ToolSystem m_ToolSystem
Reference to the ToolSystem (used to determine editor selection state, used by effect enable checks). -
private EffectControlData m_EffectControlData
Helper struct that centralizes enable/disable checks for effects. Populated in OnCreate and used by the update job. -
private NativeQuadTree<SourceInfo, QuadTreeBoundsXZ> m_SearchTree
The spatial structure holding SourceInfo entries with QuadTreeBoundsXZ bounds. This is the primary data structure consumers (rendering, audio systems, etc.) use to find nearby effect sources. -
private NativeParallelMultiHashMap<Entity, AddedSource> m_AddedSources
Tracks which sources have been added for each entity so they can be removed/updated as entities change. Keyed by Entity; value is AddedSource (m_Prefab, m_EffectIndex). -
private EntityQuery m_UpdatedEffectsQuery
Query used during normal updates to find entities that need inspecting (contains EnabledEffect and change markers, excludes Temp and certain types). -
private EntityQuery m_AllEffectsQuery
Query used when the system has just been loaded (m_Loaded) to evaluate all effects. -
private JobHandle m_ReadDependencies
Combines all job handles for jobs that read the search tree; used to produce a combined dependency for writers. -
private JobHandle m_WriteDependencies
Job handle for the current job that writes to the search tree. Readers must depend on this if write is outstanding. -
private bool m_Loaded
Flag toggled by PreDeserialize to indicate that the next update should rebuild from all effect entities (used to pick m_AllEffectsQuery). -
private TypeHandle __TypeHandle
Generated helper storing EntityTypeHandle, ComponentTypeHandle and ComponentLookup handles used by UpdateSearchTreeJob. -
private struct AddedSource
(nested)
Small struct containing: Entity m_Prefab
— prefab entity of the effect-
int m_EffectIndex
— index within the effect buffer or 0 for editor-contained effect Used to track what was added to the quad tree for a given entity. -
private struct UpdateSearchTreeJob
(nested, BurstCompile)
IJobChunk that reads relevant components (PrefabRef, Transform, Curve, Created, Deleted, etc.), inspects effect buffers and editor containers, computes bounds via GetBounds, and updates m_SearchTree and m_AddedSources accordingly. -
private struct TypeHandle
(nested)
Generated container of Entity/Component type handles and lookups, with an __AssignHandles method to initialize them from a SystemState.
Properties
- This class does not expose public properties. Interaction with the search tree is done via methods (GetSearchTree, AddSearchTreeReader, AddSearchTreeWriter).
Constructors
public SearchSystem()
Default constructor. The system initializes its fields in OnCreate. The constructor is marked with [Preserve] for linking/persistence.
Methods
-
protected override void OnCreate()
Initializes system references (EffectFlagSystem, SimulationSystem, ToolSystem), constructs m_SearchTree and m_AddedSources (persistent allocators), creates EntityQueries (m_UpdatedEffectsQuery, m_AllEffectsQuery) and initializes EffectControlData. This is where runtime dependencies for the update job are prepared. -
protected override void OnDestroy()
Disposes m_SearchTree and m_AddedSources and calls base.OnDestroy to clean up the system. -
private bool GetLoaded()
Internal helper that checks m_Loaded. If m_Loaded is true, it clears m_Loaded and returns true (causing the next update to use the full-scan query). Otherwise returns false. -
protected override void OnUpdate()
Main update function. Chooses m_AllEffectsQuery if a full rebuild is requested (loaded), otherwise m_UpdatedEffectsQuery. Updates EffectControlData with current effect flags, frame index and selected tool. Schedules UpdateSearchTreeJob over the chosen query when it is not empty. The scheduled job receives the search tree writer (via GetSearchTree) and the system stores the returned JobHandle as its dependency. After scheduling, the system registers the job as a writer with AddSearchTreeWriter so readers/writers can be synchronized. -
public NativeQuadTree<SourceInfo, QuadTreeBoundsXZ> GetSearchTree(bool readOnly, out JobHandle dependencies)
Returns the NativeQuadTree and a combined JobHandle that callers must depend on. If readOnly is true, dependencies = m_WriteDependencies (must wait for current writer). If readOnly is false, dependencies is the combination of m_ReadDependencies and m_WriteDependencies. This ensures proper synchronization between concurrent readers and the writer job. -
public void AddSearchTreeReader(JobHandle jobHandle)
Registers a job handle as a reader of the search tree (combined into m_ReadDependencies). Call this from systems/jobs that read the quad tree. -
public void AddSearchTreeWriter(JobHandle jobHandle)
Registers a job handle as the current writer for the search tree (m_WriteDependencies). The system uses this for synchronizing subsequent read requests. -
public void PreDeserialize(Context context)
Called before deserialization (loading). Completes pending dependencies for the search tree, clears the quad tree and m_AddedSources, and sets m_Loaded = true so the next update will do a full rebuild of the search tree. -
public static QuadTreeBoundsXZ GetBounds(NativeArray<Transform> transforms, NativeArray<Curve> curves, int index, Effect effect, ref ComponentLookup<LightEffectData> prefabLightEffectData, ref ComponentLookup<AudioEffectData> prefabAudioEffectData)
Static helper that computes the QuadTreeBoundsXZ for a given effect instance. It resolves the world position from curves or local transforms, composes base bounds, expands bounds for lights (m_Range) and audio (m_SourceSize) if those components exist on the effect prefab, and computes an appropriate LOD limit to store in the bounds structure. -
Generated / compiler helpers:
private void __AssignQueries(ref SystemState state)
(inlined) — generated stub used by OnCreateForCompiler.protected override void OnCreateForCompiler()
— generated entry that assigns query/type handles and calls __AssignQueries; typically called by compiler-generated initialization.-
Nested TypeHandle.__AssignHandles(ref SystemState state) — initializes all Entity/Component handles from a SystemState.
-
Nested job method notes:
- UpdateSearchTreeJob.Execute runs for each chunk and:
- Removes sources when Deleted or InterpolatedTransform present.
- For entities with EditorContainer: handles single editor prefab effect.
- For entities with PrefabRef: iterates the Effect buffer and updates the quad tree per enabled effect.
- Uses m_AddedSources to remove old/changed entries and to avoid duplicates.
- Uses m_EffectControlData.ShouldBeEnabled(...) to decide whether a source should be present.
Usage Example
// Example: reading the search tree safely in another system/job
SearchSystem searchSystem = World.GetOrCreateSystemManaged<SearchSystem>();
// In a system scheduling a job that reads the quad tree:
JobHandle readJob = someReaderJob.Schedule(...);
// Tell the SearchSystem this job reads the quad tree (so writers will wait)
searchSystem.AddSearchTreeReader(readJob);
// Alternatively, if you need direct access to the quad tree:
JobHandle deps;
var quadTree = searchSystem.GetSearchTree(readOnly: true, out deps);
// Ensure you depend on 'deps' before reading on the main thread or scheduling a dependent job
deps.Complete();
// Now read quadTree safely on the main thread
Additional notes: - The search tree and added-sources map are native containers allocated with Allocator.Persistent; they are disposed in OnDestroy. - Always respect the JobHandle returned by GetSearchTree and use AddSearchTreeReader/AddSearchTreeWriter when scheduling jobs that access the tree to maintain thread-safety. - PreDeserialize will clear and force a full rebuild on the next update; this is used during load/deserialization to ensure the search tree matches serialized world state.