Game.Tutorials.TutorialZoningTriggerSystem
Assembly: Assembly-CSharp
Namespace: Game.Tutorials
Type: public class
Base: TutorialTriggerSystemBase
Summary:
System that evaluates tutorial zoning triggers. It watches for entities that contain ZoningTriggerData and TriggerActive (and are not already TriggerCompleted). When relevant zoning changes are found (either existing zones when triggers change, or newly created zones), it schedules a Burst IJobChunk (CheckZonesJob) to scan zone cells and zone prefabs for matches against each trigger. When a match is found the system marks the trigger entity as completed (or pre-completed if the match is detected on the initial pass) and calls TutorialSystem.ManualUnlock to produce unlock events. The system integrates with the game's ZoneSystem for reading zone prefabs and with the barrier system for safe structural changes via an EntityCommandBuffer. It also uses a TypeHandle helper to cache ECS type/buffer/lookups for performance and safety.
Fields
-
private ZoneSystem m_ZoneSystem
Holds a reference to the ZoneSystem (used to get zone prefabs and register read access for job safety). -
private EntityQuery m_CreatedZonesQuery
Query selecting recently created/updated zone cells (used to detect newly created zones so triggers can be completed immediately). -
private EntityQuery m_ZonesQuery
Query selecting existing zone cells (used when triggers changed to scan all zones). -
private EntityArchetype m_UnlockEventArchetype
Archetype used by TutorialSystem.ManualUnlock to create unlock Event + Unlock components. -
private TypeHandle __TypeHandle
Helper struct instance that caches buffer/type/lookups (BufferTypeHandle, BufferTypeHandle | , BufferLookup , BufferLookup , EntityTypeHandle). Populated via __AssignHandles for safe job access. -
private struct CheckZonesJob
(nested)
Burst-compiled IJobChunk job that performs the actual checking of zone cells/prefabs against ZoningTriggerData on trigger entities. See Methods section for details of the job's members and behavior.
Properties
- (none declared in this class)
This system does not expose public properties. It uses internal fields and the TypeHandle helper to manage ECS access handles.
Constructors
public TutorialZoningTriggerSystem()
Default constructor. Marked with [Preserve] in source (so IL stripping won't remove it). The real initialization happens in OnCreate.
Methods
protected override void OnCreate()
Initializes entity queries and resources:- Sets m_ActiveTriggerQuery to select entities with ZoningTriggerData and TriggerActive but without TriggerCompleted.
- Creates m_CreatedZonesQuery and m_ZonesQuery for scanning zone cells.
- Creates m_UnlockEventArchetype (Event + Unlock).
- Acquires the ZoneSystem from the World.
-
Calls RequireForUpdate(m_ActiveTriggerQuery) so the system only runs when triggers exist. This method is marked [Preserve] in the source.
-
protected override void OnUpdate()
Main update logic: - Calls base.OnUpdate().
- If triggersChanged and there are existing zones (m_ZonesQuery non-empty), schedules a CheckZonesJob with m_FirstTimeCheck = true and passes a list of all zone archetype chunks (ToArchetypeChunkListAsync). The job will add TriggerPreCompleted + call TutorialSystem.ManualUnlock.
- Else if there are newly created zones (m_CreatedZonesQuery non-empty), schedules CheckZonesJob with m_FirstTimeCheck = false to immediately add TriggerCompleted and call ManualUnlock.
- Schedules the job in parallel using JobChunkExtensions.ScheduleParallel and combines dependencies from ToArchetypeChunkListAsync.
-
Disposes the temporary zone chunk list with dependency, registers ZoneSystem as a reader for the prefabs, and registers the job handle with the barrier system (m_BarrierSystem.AddJobHandleForProducer).
-
private void __AssignQueries(ref SystemState state)
Compiler helper used by the generated code. In this file it only creates and disposes a temporary EntityQueryBuilder. It is invoked from OnCreateForCompiler. -
protected override void OnCreateForCompiler()
Called by generated tooling; calls base.OnCreateForCompiler(), __AssignQueries, and __TypeHandle.__AssignHandles to initialize the cached type handles for job usage. -
private struct TypeHandle.__AssignHandles(ref SystemState state)
Assigns BufferTypeHandle, BufferTypeHandle | , BufferLookup , BufferLookup , and EntityTypeHandle from the provided SystemState. Used before scheduling jobs to get safe handles. -
private struct CheckZonesJob.Execute(in ArchetypeChunk chunk, int unfilteredChunkIndex, bool useEnabledMask, in v128 chunkEnabledMask)
For each entity in the passed chunk (the chunk is the active trigger entities chunk), accesses its ZoningTriggerData buffer and the entity itself. For each trigger buffer on the entity it: - Calls internal Check methods to scan the provided list of zone chunks (m_ZoneChunks) for matching zone prefabs referenced by triggerDatas.
-
If a match is found:
- If m_FirstTimeCheck is true, adds TriggerPreCompleted to the trigger entity via the parallel command buffer; otherwise adds TriggerCompleted.
- Calls TutorialSystem.ManualUnlock(...) to create unlock events using the m_UnlockEventArchetype, and to add forced unlock data or check unlock requirements via the buffer lookups.
The job obtains required handles (BufferAccessor
, Entity native array) from the input chunk.
-
private bool Check(DynamicBuffer<ZoningTriggerData> triggerDatas)
(method inside CheckZonesJob)
Iterates over the list of zone chunks and calls Check(triggerDatas, chunkCellsAccessor) to determine if any zone cell matches one of the zones referenced by the triggers. -
private bool Check(DynamicBuffer<ZoningTriggerData> triggerDatas, BufferAccessor<Cell> cellAccessor)
Iterates all cell buffers in the chunk and checks each cell buffer. -
private bool Check(DynamicBuffer<ZoningTriggerData> triggerDatas, DynamicBuffer<Cell> cells)
Looks up the zone prefab Entity for each cell using m_ZonePrefabs[cells[i].m_Zone] and compares with triggerDatas. -
private bool Check(DynamicBuffer<ZoningTriggerData> triggerDatas, Entity zone)
Compares the zone Entity against each ZoningTriggerData.m_Zone entry in the trigger buffer. Returns true on match.
Notes about the job: - The job uses BurstCompile for performance. - It uses EntityCommandBuffer.ParallelWriter to safely add components from parallel jobs. - m_FirstTimeCheck controls whether TriggerPreCompleted (first scan after triggers changed) or TriggerCompleted (immediate completion on new zones) is added. - The job obtains zone chunk list via ToArchetypeChunkListAsync and must dispose it with the job dependency.
Usage Example
[Preserve]
protected override void OnCreate()
{
base.OnCreate();
// Example of setup performed by this system:
m_ActiveTriggerQuery = GetEntityQuery(
ComponentType.ReadOnly<ZoningTriggerData>(),
ComponentType.ReadOnly<TriggerActive>(),
ComponentType.Exclude<TriggerCompleted>());
m_CreatedZonesQuery = GetEntityQuery(
ComponentType.ReadOnly<Cell>(),
ComponentType.ReadOnly<Updated>(),
ComponentType.Exclude<Temp>(),
ComponentType.Exclude<Created>(),
ComponentType.Exclude<Native>());
m_ZonesQuery = GetEntityQuery(
ComponentType.ReadOnly<Cell>(),
ComponentType.Exclude<Temp>(),
ComponentType.Exclude<Created>(),
ComponentType.Exclude<Native>());
m_UnlockEventArchetype = EntityManager.CreateArchetype(
ComponentType.ReadWrite<Event>(),
ComponentType.ReadWrite<Unlock>());
m_ZoneSystem = World.GetOrCreateSystemManaged<ZoneSystem>();
RequireForUpdate(m_ActiveTriggerQuery);
}
Additional notes for modders: - To create a zoning tutorial trigger, add an entity with a ZoningTriggerData buffer (one or more entries referencing zone prefab Entities) and TriggerActive component. This system will detect when the referenced zone Entities appear in the city. - When the system finds a matching zone it will add TriggerPreCompleted if it was the initial scan after trigger changes, or TriggerCompleted if the zone was newly created; it will then call TutorialSystem.ManualUnlock which produces unlock Events (using the m_UnlockEventArchetype). - If you create or remove zone prefabs/entities, ensure proper ordering with ZoneSystem readers/writers; this system registers itself as a reader via m_ZoneSystem.AddPrefabsReader(base.Dependency) when scheduling jobs. - The system is ECS-based and uses jobs + command buffers for safe structural changes; modifications to entities/components outside this pattern should be carefully synchronized to avoid race conditions or safety errors. - Methods/fields marked with [Preserve] or CompilerGenerated are important for runtime linking and code stripping behavior — keep these annotations when copying or modifying this pattern.