Skip to content

Game.Effects.EffectControlSystem

Assembly: Assembly-CSharp
Namespace: Game.Effects

Type: class

Base: GameSystemBase, IPostDeserialize

Summary: EffectControlSystem is the central DOTS system that manages enabling and disabling of prefab effects (VFX, audio, lights and similar effect instances) for game objects and prefabs. It collects per-owner effect buffers (EnabledEffect), evaluates culling and LOD (using camera parameters, pre-culling data and quadtrees), schedules jobs to add/remove enabled effect instances, and populates a contiguous NativeList of EnabledEffectData used by downstream systems (VFXSystem, audio, lighting, etc.). The system heavily uses Unity Jobs, Burst-compatible structs, Native containers and component lookups to operate in parallel and to minimize main-thread work.

The system coordinates: - Per-chunk scanning to find owners and their enabled effects (EffectControlJob). - Pre-culling updates when pre-culling data changes (EffectCullingJob). - Quadtree-based LOD transitions (TreeCullingJob1/2 + TreeCullingIterator). - Converting culling/action events into enabled/disabled state updates and enqueueing VFX/audio updates (EnabledActionJob). - Resizing and finalizing the EnabledEffectData buffer (ResizeEnabledDataJob).

It integrates with other systems: VFXSystem, SearchSystem, PreCullingSystem, EffectFlagSystem, SimulationSystem, CameraUpdateSystem, RenderingSystem and BatchDataSystem.


Fields

  • private VFXSystem m_VFXSystem
    Provides access to the VFX subsystem; used to enqueue VFX source updates when effects are enabled/disabled.

  • private SearchSystem m_SearchSystem
    Provides the effect search quadtree used for LOD-based culling across the world.

  • private EffectFlagSystem m_EffectFlagSystem
    Used to query effect-related flags/state.

  • private SimulationSystem m_SimulationSystem
    Used to access simulation frame index and other simulation-level info affecting effect evaluation.

  • private PreCullingSystem m_PreCullingSystem
    Provides pre-culling data and readers; used to determine which owners are near the camera and require updates.

  • private ToolSystem m_ToolSystem
    Used to include tool/editor selections in effect decisions (e.g., EditorContainer prefabs).

  • private RenderingSystem m_RenderingSystem
    Used for frame LOD and rendering-relative info.

  • private BatchDataSystem m_BatchDataSystem
    Used to compute camera/LOD parameters for rendering culling decisions.

  • private CameraUpdateSystem m_CameraUpdateSystem
    Provides LOD/camera position and viewer forward direction used for effect LOD checks.

  • private EffectControlData m_EffectControlData
    Holds shared data and helper logic (encapsulates lookups like m_Prefabs, m_Temps etc.) for effect enable/disable evaluation.

  • private NativeList<EnabledEffectData> m_EnabledData
    Contiguous native list storing data for all currently tracked enabled effects. This is the main result consumers read (VFX/audio/light systems).

  • private EntityQuery m_UpdatedEffectsQuery
    EntityQuery used for incremental updates (entities that changed relevant components).

  • private EntityQuery m_AllEffectsQuery
    EntityQuery used when loading/initial full rebuild is required.

  • private JobHandle m_EnabledWriteDependencies
    JobHandle tracking writers to m_EnabledData so other systems can schedule safely.

  • private JobHandle m_EnabledReadDependencies
    JobHandle tracking readers to m_EnabledData.

  • private float3 m_PrevCameraPosition
    Cached previous camera position used to detect LOD transitions between frames.

  • private float3 m_PrevCameraDirection
    Cached previous camera forward direction for LOD calculations.

  • private float4 m_PrevLodParameters
    Cached previous LOD parameters used to compare previous frame LOD results.

  • private bool m_Loaded
    Flag set when PostDeserialize informs the system data has been loaded; triggers full-scan behavior on next update.

  • private bool m_ResetPrevious
    Flag to indicate previous camera/LOD values should be reset on next update (e.g., after deserialization).

  • private TypeHandle __TypeHandle
    Internal aggregated type handles used to schedule jobs (auto-generated helper storing component/buffer/lookup handles).


Properties

  • None (this system exposes functionality through methods).

Constructors

  • public EffectControlSystem()
    Default constructor (marked [Preserve] on lifecycle methods). Initializes the system instance; most initialization happens in OnCreate (systems fetched/created, NativeList allocated, queries created).

{{ The system follows Unity ECS lifecycle: heavy initialization is in OnCreate, resources are disposed in OnDestroy. The constructor itself is minimal, as is standard for managed systems. }}


Methods

  • protected override void OnCreate()
    Initializes references to other systems (VFXSystem, SearchSystem, PreCullingSystem, etc.), creates EffectControlData helper, allocates m_EnabledData (NativeList with Allocator.Persistent), and creates the entity queries used for incremental/full updates.

  • protected override void OnDestroy()
    Disposes m_EnabledData and performs usual cleanup.

  • public void PostDeserialize(Context context)
    IPostDeserialize implementation. Completes outstanding EnabledData job dependencies, clears m_EnabledData, and sets flags so the system performs a full rebuild in the next update. Call is used after serialization/deserialization to repair state.

  • public NativeList<EnabledEffectData> GetEnabledData(bool readOnly, out JobHandle dependencies)
    Returns the NativeList of EnabledEffectData and out-parameters a JobHandle that represents dependencies the caller must satisfy. If readOnly is true, returns m_EnabledWriteDependencies (so readers wait on writers), otherwise returns the combined writer+reader dependency. Use AddEnabledDataReader/AddEnabledDataWriter to register additional handles.

  • public void AddEnabledDataReader(JobHandle dependencies)
    Combines the provided dependencies into the system's m_EnabledReadDependencies. Call when a job is reading m_EnabledData to ensure proper synchronization.

  • public void AddEnabledDataWriter(JobHandle dependencies)
    Sets m_EnabledWriteDependencies to a writer handle issued by a job that will write to m_EnabledData. This prevents concurrent modifications.

  • public void GetLodParameters(out float4 lodParameters, out float3 cameraPosition, out float3 cameraDirection)
    Returns the previous-frame LOD parameters and camera info cached by the system. Useful for other systems that need consistent camera/LOD data used by effect culling.

  • private bool GetLoaded()
    Private helper to consume the m_Loaded flag and return true the first time after loading. Used to trigger full rebuild logic once after deserialization.

  • protected override void OnUpdate()
    Main update loop. High-level responsibilities:

  • Determine whether to run a full rebuild (loaded) or incremental update (updated query).
  • Update internal EffectControlData using current frame info (selected tool, flags, frame index).
  • Acquire camera/LOD parameters (from CameraUpdateSystem, BatchDataSystem).
  • Schedule EffectControlJob (IJobChunk) to scan entity chunks for EnabledEffect buffers and enqueue EnabledAction items into a NativeParallelQueue.
  • Optionally schedule quadtree tree culling jobs (TreeCullingJob1/2) and EffectCullingJob for pre-culling updates.
  • Schedule EnabledActionJob (IJobParallelFor) which consumes the action queue and updates m_EnabledData and per-owner EnabledEffect buffers (adding/removing enabled indices).
  • Schedule ResizeEnabledDataJob to resize and finalize m_EnabledData and handle overflow cases.
  • Wire up JobHandles into m_EnabledWriteDependencies and base.Dependency so other systems can depend on these results.

  • protected override void OnCreateForCompiler()
    Auto-generated helper used by compilation/time-of-build to assign queries/handles.

  • private void __AssignQueries(ref SystemState state)
    Auto-generated (compiler) method to set up any additional queries used by the system at compile-time.

Nested job/struct summaries: - EffectControlJob (IJobChunk, Burst compiled)
Scans chunks, looks at EnabledEffect buffers, PrefabRef/EditorContainer, CullingInfo and decides per-owner actions: WrongPrefab, Deleted, CheckEnabled, IsStatic and OwnerUpdated flags, enqueueing EnabledAction entries.

  • EffectCullingJob (IJobParallelForDefer, Burst compiled)
    Processes PreCullingData list entries and enqueues enable/disable actions for effects whose owner-culling changed.

  • TreeCullingJob1/TreeCullingJob2 + TreeCullingIterator
    Walks the effect quadtree (NativeQuadTree) to detect LOD transitions for individual effect sources and enqueue actions accordingly.

  • EnabledActionJob (IJobParallelFor, Burst compiled)
    Processes action queue entries and actually enables/disables effect instances: updates per-owner EnabledEffect buffers, allocates new EnabledEffectData entries (Interlocked increment), enqueues VFX updates to VFXSystem, handles overflow into a temporary queue which ResizeEnabledDataJob will drain.

  • ResizeEnabledDataJob (IJob)
    Ensures m_EnabledData is resized to the final size after EnabledActionJob mutated it; drains overflow queue to populate any entries that were produced while capacity was exceeded.

Notes about concurrency: - The system uses NativeParallelQueue to collect candidate enable/disable actions from many jobs. - m_EnabledData is updated in parallel by EnabledActionJob using an atomic index (NativeReference m_EnabledDataIndex) and then finalized in ResizeEnabledDataJob. - External consumers must use AddEnabledDataReader/AddEnabledDataWriter and GetEnabledData to obtain and respect JobHandles for safe access.


Usage Example

// Get the system from the World and read the enabled effect data (read-only).
var effectSystem = World.DefaultGameObjectInjectionWorld.GetOrCreateSystemManaged<Game.Effects.EffectControlSystem>();

// If calling from a main-thread context (not scheduling DOTS jobs), you can request data like this:
JobHandle deps;
NativeList<Game.Effects.EnabledEffectData> enabledData = effectSystem.GetEnabledData(readOnly: true, out deps);

// Ensure outstanding writer jobs complete before accessing on main thread.
deps.Complete();

// Iterate enabledData safely on main thread (remember to not hold it beyond frame without proper synchronization).
for (int i = 0; i < enabledData.Length; i++)
{
    var ed = enabledData[i];
    // ed.m_Owner, ed.m_Prefab, ed.m_EffectIndex, ed.m_Flags etc.
}

// If scheduling a job that reads enabledData, call:
// effectSystem.AddEnabledDataReader(jobHandleForYourReadJob);

// If your job writes to enabledData (very rare), call:
// effectSystem.AddEnabledDataWriter(jobHandleForYourWriteJob);

{{YOUR_INFO}}