Game.NotificationIconLocationSystem
Assembly: Assembly-CSharp
Namespace: Game.Rendering
Type: class
Base: GameSystemBase
Summary:
NotificationIconLocationSystem is an ECS system that updates the world-space location of UI notification icons so they sit above their associated in-game objects. It schedules a Burst-compiled IJobChunk (NotificationIconMoveJob) which reads the owner entity's InterpolatedTransform and the owner's Prefab/Object geometry data to compute the top y position of the object's bounds and sets the icon's location (xz from the transform position, y at the bounds' max). The system uses an EntityQuery filtered to active Icon components and runs only when relevant entities exist. The implementation is optimized for the Jobs system and uses ComponentTypeHandle/ComponentLookup caching for performance.
Fields
-
private EntityQuery m_IconQuery
Holds the EntityQuery used by the system to select Icon entities. The query requires Icon (read/write) and matches entities that have either DisallowCluster or Game.Notifications.Animation, and excludes Deleted. RequireForUpdate(m_IconQuery) is used so the system only runs when matching entities exist. -
private TypeHandle __TypeHandle
A private struct instance used to cache ComponentTypeHandle and ComponentLookup instances (for Owner, Temp, Icon, InterpolatedTransform, PrefabRef and ObjectGeometryData). The cached handles are assigned during OnCreateForCompiler via __AssignHandles for efficient access during job scheduling. -
private struct NotificationIconMoveJob
(nested)
Burst-compiled IJobChunk that performs the per-chunk logic. Reads Owner and Temp, writes Icon, and reads InterpolatedTransform, PrefabRef and ObjectGeometryData via ComponentLookup. For each entity in the chunk it: - Skips entities where Temp indicates a non-null original entity (in archetypes that include Temp) — effectively only handles icons not associated with an "original" override.
- Checks the owner entity has an InterpolatedTransform.
-
Reads the owner's PrefabRef and InterpolatedTransform, calculates object bounds via ObjectUtils.CalculateBounds, sets icon.m_Location.xz to the owner's position.xz and icon.m_Location.y to the bounds.max.y. This job is scheduled in parallel from OnUpdate.
-
private struct TypeHandle
(nested)
Contains the ComponentTypeHandle and ComponentLookup fields used by the job and a __AssignHandles method which obtains handles from a SystemState (GetComponentTypeHandle / GetComponentLookup). This is called during OnCreateForCompiler to initialize the handles used later when scheduling jobs.
Properties
- None. The system exposes no public properties.
Constructors
public NotificationIconLocationSystem()
Default parameterless constructor (empty). The system lifecycle is driven by the ECS base class (GameSystemBase) and the overridden OnCreate/OnUpdate methods.
Methods
protected override void OnCreate()
Creates and configures the EntityQuery (m_IconQuery) used to find Icon entities to process:- All: Icon (read/write)
- Any: DisallowCluster (read-only) OR Game.Notifications.Animation (read-only)
-
None: Deleted (read-only) Calls RequireForUpdate(m_IconQuery) so the system runs only if matching entities exist.
-
protected override void OnUpdate()
Builds and schedules the NotificationIconMoveJob using JobChunkExtensions.ScheduleParallel with the m_IconQuery. It populates the job's ComponentTypeHandle and ComponentLookup fields using InternalCompilerInterface.GetComponentTypeHandle / GetComponentLookup while passing the cached handles from __TypeHandle. The returned JobHandle is stored to base.Dependency. -
protected override void OnCreateForCompiler()
Called to perform compiler-time setup: it calls __AssignQueries (no-op here) and __TypeHandle.__AssignHandles to obtain the component handles from the system state. This prepares the TypeHandle cache used when scheduling the job. -
private void __AssignQueries(ref SystemState state)
Present for compiler integration and currently a no-op aside from creating/disposing a temporary EntityQueryBuilder. Intended to be used by generated code paths; keeps a place for query assignment if needed by the compilation pipeline. -
private void TypeHandle.__AssignHandles(ref SystemState state)
(Defined inside the nested TypeHandle) Assigns the ComponentTypeHandle and ComponentLookup fields from the provided SystemState. Marks which handles are read-only as appropriate. -
private struct NotificationIconMoveJob.Execute(...)
(Inside the job) The core per-chunk processing logic described in the Fields section. Iterates chunk entities, reads Owner/Temp/Icon arrays and performs location adjustments when the owner has an InterpolatedTransform and the Temp check passes.
Usage Example
[Preserve]
protected override void OnCreate()
{
base.OnCreate();
// The system already creates an EntityQuery for Icon components in its OnCreate,
// so in a mod you would usually not need to change this. This snippet mirrors
// the system's behavior and ensures it updates only when Icon entities exist.
m_IconQuery = GetEntityQuery(new EntityQueryDesc
{
All = new[] { ComponentType.ReadWrite<Icon>() },
Any = new[] { ComponentType.ReadOnly<DisallowCluster>(), ComponentType.ReadOnly<Game.Notifications.Animation>() },
None = new[] { ComponentType.ReadOnly<Deleted>() }
});
RequireForUpdate(m_IconQuery);
}
Notes and implementation details: - The job is Burst-compiled and scheduled in parallel to maximize throughput for many icons. - The Temp component check uses a double-negative in code; logically the job processes an icon when the Temp archetype is absent OR when Temp.m_Original == Entity.Null. - InterpolatedTransform is required on the owner entity to compute the icon position; the system checks HasComponent(owner) before reading transform/PrefabRef/ObjectGeometryData. - The icon's XZ is set to the owner's world XZ position; the Y is set to the top (max.y) of the object's calculated bounds so the icon appears above the object.