Game.Tutorials.TutorialAutoActivationSystem
Assembly: Assembly-CSharp
Namespace: Game.Tutorials
Type: public class
Base: GameSystemBase
Summary:
System that automatically activates tutorial entities when their required unlock condition is met. It queries entities with AutoActivationData that are not already TutorialCompleted or TutorialActivated, checks whether the referenced unlock entity is unlocked (i.e., does not have an enabled Locked component), and, if so, adds a TutorialActivated component to the entity via a parallel command buffer. The activation logic runs as a parallel IJobChunk (ActivateJob) compiled with Burst for performance and uses the ModificationBarrier4 command buffer system to write component additions safely from jobs.
Fields
-
private EntityCommandBufferSystem m_BarrierSystem
Holds a reference to the barrier (ModificationBarrier4) used to create an EntityCommandBuffer for adding components from the job. This barrier is acquired in OnCreate via World.GetOrCreateSystemManaged(). -
private EntityQuery m_AutoActivateQuery
EntityQuery that selects entities with AutoActivationData and excludes TutorialCompleted and TutorialActivated. Used to determine whether work needs to be scheduled. -
private TypeHandle __TypeHandle
Compiler-generated struct that stores EntityTypeHandle, ComponentLookup(read-only), and ComponentTypeHandle (read-only). __AssignHandles fills these handles from the SystemState for use in jobs. -
(nested)
private struct ActivateJob
Burst-compiled IJobChunk that does the actual per-chunk work. It reads entities and AutoActivationData, checks the Locked component on the referenced entity, and issues AddComponentvia an EntityCommandBuffer.ParallelWriter when the required unlock is not present (i.e., the unlock is available). -
(nested)
private struct TypeHandle
Compiler-generated helper for holding and assigning the various type handles (EntityTypeHandle, ComponentLookup, ComponentTypeHandle ) used by the job.
Properties
- No public properties on this system.
Constructors
public TutorialAutoActivationSystem()
Default constructor (annotated with [Preserve] in the class). The system initialization is performed in the OnCreate override.
Methods
-
protected override void OnCreate()
Initializes the system: acquires the ModificationBarrier4 system for command buffering and creates the entity query: GetEntityQuery(ComponentType.ReadOnly(), ComponentType.Exclude (), ComponentType.Exclude ). -
protected override void OnUpdate()
If the query is non-empty, constructs and schedules the ActivateJob as a parallel JobChunk. It fills jobData with: - m_EntityType from __TypeHandle,
- m_LockedDataFromEntity from __TypeHandle,
- m_AutoActivationDataTypeHandle from __TypeHandle,
-
m_Writer from m_BarrierSystem.CreateCommandBuffer().AsParallelWriter(). The job is scheduled in parallel and the resulting dependency is handed to the barrier via AddJobHandleForProducer.
-
protected override void OnCreateForCompiler()
Compiler helper that assigns queries and type handles for the generated code path. Calls __AssignQueries and __TypeHandle.__AssignHandles. -
private void __AssignQueries(ref SystemState state)
Compiler-generated placeholder that currently only constructs and disposes an empty EntityQueryBuilder(Allocator.Temp). Part of generated plumbing; real query setup is in OnCreate. -
(nested) ActivateJob.Execute(in ArchetypeChunk chunk, int unfilteredChunkIndex, bool useEnabledMask, in v128 chunkEnabledMask)
Iterates entities in the chunk, reads AutoActivationData for each entity, and checks the referenced unlock entity with m_LockedDataFromEntity.HasEnabledComponent(autoActivationData.m_RequiredUnlock). If the referenced entity does not have the Locked enabled component, it adds TutorialActivated to the entity via the parallel command buffer writer.
Notes and behavior details: - The job reads AutoActivationData and Locked in read-only fashion; it writes only via ECB.AddComponent to avoid structural changes during iteration. - Uses InternalCompilerInterface helpers (GetEntityTypeHandle/GetComponentLookup/GetComponentTypeHandle) to obtain handles tied to the system's checked state. - The ActivateJob is marked [BurstCompile] for better runtime performance, and scheduling uses JobChunkExtensions.ScheduleParallel to process chunks in parallel.
Usage Example
[Preserve]
protected override void OnCreate()
{
base.OnCreate();
m_BarrierSystem = base.World.GetOrCreateSystemManaged<ModificationBarrier4>();
m_AutoActivateQuery = GetEntityQuery(
ComponentType.ReadOnly<AutoActivationData>(),
ComponentType.Exclude<TutorialCompleted>(),
ComponentType.Exclude<TutorialActivated>()
);
}
[Preserve]
protected override void OnUpdate()
{
if (!m_AutoActivateQuery.IsEmptyIgnoreFilter)
{
ActivateJob jobData = new ActivateJob
{
m_EntityType = InternalCompilerInterface.GetEntityTypeHandle(ref __TypeHandle.__Unity_Entities_Entity_TypeHandle, ref base.CheckedStateRef),
m_LockedDataFromEntity = InternalCompilerInterface.GetComponentLookup(ref __TypeHandle.__Game_Prefabs_Locked_RO_ComponentLookup, ref base.CheckedStateRef),
m_AutoActivationDataTypeHandle = InternalCompilerInterface.GetComponentTypeHandle(ref __TypeHandle.__Game_Tutorials_AutoActivationData_RO_ComponentTypeHandle, ref base.CheckedStateRef),
m_Writer = m_BarrierSystem.CreateCommandBuffer().AsParallelWriter()
};
base.Dependency = JobChunkExtensions.ScheduleParallel(jobData, m_AutoActivateQuery, base.Dependency);
m_BarrierSystem.AddJobHandleForProducer(base.Dependency);
}
}
Additional tips for modders: - Ensure AutoActivationData.m_RequiredUnlock references the entity whose Locked component controls the tutorial activation. The system treats the absence (or disabled state) of the Locked component as "unlocked". - If you author entities that should auto-activate tutorials, add AutoActivationData and ensure they do not have TutorialCompleted or TutorialActivated initially. - Because this system schedules a Burst-compiled parallel job and writes via an ECB, avoid making structural changes to the same entities from other systems without proper dependency handling. - If you need to debug activation behavior, consider temporarily disabling Burst or adding a debug system that logs when TutorialActivated is added.