Game.Objects.UpdateCollectSystem
Assembly:
Namespace: Game.Objects
Type: class
Base: GameSystemBase
Summary:
UpdateCollectSystem collects and exposes 2D bounds (Bounds2) of objects that were Created, Updated or Deleted during a frame. It queries object entities (Object + Static + Transform + PrefabRef) and uses a combination of a static search tree and prefab geometry to compute the bounds. Work is performed with Burst-compiled jobs (IJobChunk and IJob), using a NativeQueue to gather results on worker threads and a NativeList to store the final list of updated bounds for other systems to consume. The system also exposes dependency handles so other jobs can safely read those bounds.
Fields
-
private Unity.Entities.EntityQuery m_ObjectQuery
Holds the entity query used to find object entities to inspect. Query All: Object, Static, Transform, PrefabRef. Any: Created, Updated, Deleted. None: Temp. -
private SearchSystem m_SearchSystem
Reference to the SearchSystem used to read the static search tree (static object bounds) for existing entities. -
private Unity.Collections.NativeList<Bounds2> m_UpdatedBounds
Persistent NativeList that stores the final list of updated Bounds2 produced by the system each frame. Returned to callers via GetUpdatedBounds. -
private Unity.Jobs.JobHandle m_WriteDependencies
JobHandle representing the most recent writer dependency (jobs that produced/wrote m_UpdatedBounds). Returned by GetUpdatedBounds as the dependencies that consumers must wait on. -
private Unity.Jobs.JobHandle m_ReadDependencies
Aggregated JobHandle of reader dependencies that this system should wait for before producing new data (consumers can add their read handles with AddBoundsReader). -
private TypeHandle __TypeHandle
Internal container of the various EntityTypeHandle / ComponentTypeHandle / ComponentLookup used by the jobs. Populated in __AssignHandles.
Properties
public bool isUpdated { get; private set; }
True while the system has been updated this frame (set to true at start of OnUpdate). Cleared to false in OnStopRunning. Can be used to quickly check whether the system collected any bounds this runtime frame.
Constructors
public UpdateCollectSystem()
Default constructor (empty). System initialization is performed in OnCreate.
Methods
-
protected override void OnCreate()
: System.Void
Initializes the system: acquires a reference to SearchSystem, creates the entity query for objects, allocates m_UpdatedBounds (Allocator.Persistent), and calls RequireForUpdate(m_ObjectQuery) so the system runs only when matching entities exist. -
protected override void OnDestroy()
: System.Void
Disposes m_UpdatedBounds and calls base.OnDestroy(). -
protected override void OnStopRunning()
: System.Void
Completes outstanding write/read dependencies, clears m_UpdatedBounds, sets isUpdated = false, and calls base.OnStopRunning(). -
protected override void OnUpdate()
: System.Void
Main runtime logic: - Sets isUpdated = true.
- Creates a NativeQueue
(TempJob) for workers to enqueue computed bounds. - Prepares and schedules a Burst-compiled IJobChunk (CollectUpdatedObjectBoundsJob) that:
- For Created entities: computes bounds from prefab geometry (ObjectGeometryData + ObjectUtils.CalculateBounds) and enqueues them.
- For Deleted entities: looks up existing bounds in the SearchSystem tree and enqueues them.
- For Updated entities: attempts to read both existing bounds (from search tree) and recomputed bounds (from prefab geometry), then either enqueues the merged bounds or both parts depending on overlap/size logic.
- Uses m_SearchSystem.GetStaticSearchTree(readOnly: true, out dependencies) to obtain the static tree and producer dependencies.
- Schedules a DequeueBoundsJob (IJob) that transfers queued Bounds2 from the NativeQueue into the persistent m_UpdatedBounds NativeList.
- Disposes the queue with the combined dependency of the Dequeue job.
- Adds the Collect job as a static search tree reader (m_SearchSystem.AddStaticSearchTreeReader(jobHandle)) so readers are tracked.
-
Updates m_WriteDependencies and base.Dependency to chain further work correctly.
-
public NativeList<Bounds2> GetUpdatedBounds(out Unity.Jobs.JobHandle dependencies)
: NativeList
Returns the NativeList containing the updated bounds and outputs the JobHandle (m_WriteDependencies) that consumers must complete before reading the list. -
public void AddBoundsReader(Unity.Jobs.JobHandle handle)
: System.Void
Allows external code to add a read dependency that this system will combine into m_ReadDependencies. This ensures the system waits for provided readers before modifying or producing new data. -
protected override void OnCreateForCompiler()
: System.Void
Compiler helper used to assign queries and type handles (calls __AssignQueries and __TypeHandle.__AssignHandles). Present for generated/compiled compatibility. -
private void __AssignQueries(ref Unity.Entities.SystemState state)
: System.Void
Internal method used by the compiler flow. In this class it creates an EntityQueryBuilder (temporary) and disposes it; real handles are assigned in __AssignHandles.
Nested/Burst jobs (high level):
- CollectUpdatedObjectBoundsJob : IJobChunk (BurstCompile)
- Read-only handles: EntityTypeHandle, Transform, PrefabRef, Created, Deleted, ComponentLookup
. - Read-only NativeQuadTree
m_SearchTree (retrieved from SearchSystem). - NativeQueue
.ParallelWriter m_ResultQueue used to push results from worker threads. -
Logic:
- If chunk has Created: iterate PrefabRef+Transform, compute geometry bounds from ObjectGeometryData (if present) and enqueue their xz bounds.
- Else if chunk has Deleted: iterate Entities, lookup existing bounds in m_SearchTree and enqueue stored xz bounds.
- Else (Updated): for each entity try to get existing bounds from m_SearchTree and compute new prefab geometry bounds if available; combine them:
- If both exist: compute union and if the union's size is less than sum of parts (i.e., overlapping) enqueue the union; otherwise enqueue both separately.
- If only existing or only computed bounds exist, enqueue the one present.
-
DequeueBoundsJob : IJob (BurstCompile)
- Pulls all entries from a NativeQueue
and writes them into a NativeList (m_UpdatedBounds). Uses ResizeUninitialized(count) then populates the list.
Notes and implementation details:
- Uses BurstCompile on the jobs for performance.
- Uses NativeQueue.AsParallelWriter to allow the IJobChunk to enqueue from worker threads.
- Prefab geometry is obtained via ComponentLookup
Usage Example
[Preserve]
protected override void OnCreate()
{
base.OnCreate();
m_SearchSystem = base.World.GetOrCreateSystemManaged<SearchSystem>();
m_ObjectQuery = GetEntityQuery(new EntityQueryDesc
{
All = new ComponentType[4]
{
ComponentType.ReadOnly<Object>(),
ComponentType.ReadOnly<Static>(),
ComponentType.ReadOnly<Transform>(),
ComponentType.ReadOnly<PrefabRef>()
},
Any = new ComponentType[3]
{
ComponentType.ReadOnly<Created>(),
ComponentType.ReadOnly<Updated>(),
ComponentType.ReadOnly<Deleted>()
},
None = new ComponentType[1] { ComponentType.ReadOnly<Temp>() }
});
m_UpdatedBounds = new NativeList<Bounds2>(Allocator.Persistent);
RequireForUpdate(m_ObjectQuery);
}
Additional quick example (reading updated bounds safely):
// Somewhere after UpdateCollectSystem runs:
var updatedBounds = updateCollectSystem.GetUpdatedBounds(out JobHandle produceDeps);
// If scheduling a job that reads updatedBounds, combine its handle and then call:
// updateCollectSystem.AddBoundsReader(readerJobHandle);
// Ensure to complete produceDeps before directly reading the NativeList on the main thread.