Game.Objects.AlignSystem
Assembly: Assembly-CSharp (typical for game mod assemblies)
Namespace: Game.Objects
Type: class
Base: GameSystemBase
Summary:
AlignSystem is an ECS system responsible for aligning "sub-objects" (attachments, pillars, placeable parts of prefabs) relative to their owners (nodes/edges or other parent objects). It runs as a job over entities that have Updated + Aligned components (and are not Deleted) and updates Transform, Stack, and related data for sub-objects. The system uses a nested Burst-compiled AlignJob to do heavy computations in parallel, and writes structural changes through a ModificationBarrier (EntityCommandBuffer). It consults terrain and water height data and several prefab/component lookups (geometry, pillar data, placeholder objects, etc.) to decide placement, rotation, height, and whether to remove objects that no longer fit.
Fields
-
private ModificationBarrier4 m_ModificationBarrier
This barrier is used to obtain an EntityCommandBuffer for safely making structural/entity changes from the job (removing/adding components, setting components). -
private TerrainSystem m_TerrainSystem
Reference to the TerrainSystem used to obtain terrain height data required for ground alignment. -
private WaterSystem m_WaterSystem
Reference to the WaterSystem used to obtain water surface data (water height/depth) used to determine placement on water vs terrain. -
private EntityQuery m_UpdateQuery
Query selecting entities to process: it requires Updated and Aligned and excludes Deleted. Used to build the chunk list for the AlignJob. -
private ComponentTypeSet m_AppliedTypes
A set of component types applied when removing an object (Used with m_CommandBuffer). Contains Applied, Created, Updated (read/write in this system). -
private TypeHandle __TypeHandle
Holds all EntityTypeHandle / ComponentTypeHandle / ComponentLookup / BufferLookup needed by the job. Populated in __AssignHandles. -
private struct AlignJob
(nested)
Burst-compiled IJob containing the core alignment logic executed in parallel over archetype chunks. The job holds many ComponentLookup/BufferLookup and a NativeListof chunks to process. -
private struct TypeHandle
(nested)
Helper struct that stores the component/lookup handles and assigns them from a SystemState. Used to initialize __TypeHandle.
Properties
- (none public on this system)
{{ The system does not expose public properties. All important state is kept private and manipulated internally or through ECS components. }}
Constructors
public AlignSystem()
Default constructor. Annotated with [Preserve] in the source to avoid stripping. It only calls the base constructor (no custom runtime initialization is done here; initialization happens in OnCreate).
{{ The system is created by the world (EntityManager). Use world.GetOrCreateSystemManaged
Methods
protected override void OnCreate()
: System.Void
Initializes the system: retrieves ModificationBarrier4, TerrainSystem, WaterSystem; builds the EntityQuery that selects Updated + Aligned (excludes Deleted); prepares the ComponentTypeSet m_AppliedTypes; calls RequireForUpdate(m_UpdateQuery) so the system runs only when matching entities exist.
{{ OnCreate wires up dependencies and prepares component sets/queries required by the AlignJob. The method is preserved to prevent IL stripping. }}
protected override void OnUpdate()
: System.Void
Main update function. It:- Collects archetype chunks that match m_UpdateQuery asynchronously.
- Builds and schedules the AlignJob (Burst) with all ComponentTypeHandles / ComponentLookups / BufferLookups and the chunk list.
- Requests terrain height and water surface data from respective systems (and registers job dependencies).
- Disposes the chunk list once the job is scheduled.
- Adds job handles to m_ModificationBarrier / TerrainSystem / WaterSystem for producer/reader tracking.
- Sets base.Dependency to the scheduled job handle.
{{ This method schedules the job-based alignment and manages inter-system synchronization (terrain/water readers, modification barrier). }}
protected override void OnCreateForCompiler()
: System.Void
Compiler-facing OnCreate used when source is generated/compiled; assigns queries and TypeHandles via helper methods.
{{ Internal setup method used to ensure handles and queries are assigned in generated builds. }}
private void __AssignQueries(ref SystemState state)
: System.Void
Internal helper to (re)assign entity queries. In this source it currently just calls a disposable EntityQueryBuilder — a placeholder to match generated code patterns.
{{ Generated/placeholder method; real query assignment is done in OnCreate. }}
- Nested AlignJob methods (inside the job, burst compiled):
-
Execute()
Iterates matching chunks, reads Aligned/Owner/PrefabRef/Attached etc., and for non-attached entities calls Align then MoveObject if transform changed. -
Align(Entity entity, Aligned aligned, Owner owner, PrefabRef prefabRef, bool isTemp, ref Transform transform)
Main alignment routine. Finds proper sub-object index and subobject definition on the owner's prefab, determines whether alignment is along a Curve (edge) or Node, computes base transform, handles pillar rules and flags, and delegates to AlignVerticalPillars, AlignHeight, etc. -
MoveObject(Entity entity, Transform oldTransform, Transform newTransform)
Writes transform for entity, then recursively updates eligible child sub-objects (that have Updated and not Aligned themselves) using local-to-world transformations. -
AlignVerticalPillars(...)
Coordinates vertical pillar alignment: finds vertical pillars and either aligns single or double pillars, or selects appropriate horizontal pillar prefabs when needed. -
AlignSingleVerticalPillar(...) and AlignDoubleVerticalPillars(...)
Detailed logic to align one or a pair of vertical pillar entities relative to parent transform, including rotation alignment, spacing, selecting horizontal filler prefab variants, and possible removal of too-close pillars. -
SelectHorizontalPillar(Entity entity, SubObject prefabSubObject, float targetWidth, Bounds1 offsetRange1, Bounds1 offsetRange2, ref PrefabRef prefabRef)
Chooses a horizontal pillar prefab from placeholder objects that best matches the target width and offset constraints. May update the entity's PrefabRef (through the command buffer). -
FindVerticalPillars(...) : bool
Searches for other vertical pillars that belong to the same owner and have the same sub-object index, either by scanning temp chunks or the owner's SubObject buffer. Returns whether any pillar found and outputs up to two pillars. -
AlignHeight(...)
Adjusts transform.m_Position.y according to subobject flags (AnchorTop, AnchorCenter, OnGround), queries terrain/water heights, and updates Stack component range if present. Supports stack alignment via StackData / Stack components. -
AlignRotation(quaternion targetRotation, ref Transform transform)
Snaps/chooses transform.m_Rotation among four 90-degree rotated candidates to minimize rotation angle to targetRotation (helps keep pillar/fitting orientations aligned nicely). -
RemoveObject(Entity entity, Attached attached, Owner owner)
Removes the object's relevant "applied" components via the command buffer and marks it as Deleted; also removes it from parent's and owner's SubObject buffers where present.
{{ The AlignJob contains the core algorithmic details: selecting sub-object index, computing placement on edges or nodes, pillar handling (vertical/horizontal selection), rotation snapping, height/water handling, stack updates, and commanded deletions. Most work is done read-only via lookups and results are written back to Transform/Stack or via the command buffer for structural changes. }}
Usage Example
// The system is typically part of the game's world and runs automatically.
// Example snippet showing how the system initializes in OnCreate (taken from source):
[Preserve]
protected override void OnCreate()
{
base.OnCreate();
m_ModificationBarrier = base.World.GetOrCreateSystemManaged<ModificationBarrier4>();
m_TerrainSystem = base.World.GetOrCreateSystemManaged<TerrainSystem>();
m_WaterSystem = base.World.GetOrCreateSystemManaged<WaterSystem>();
m_UpdateQuery = GetEntityQuery(ComponentType.ReadOnly<Updated>(),
ComponentType.ReadOnly<Aligned>(),
ComponentType.Exclude<Deleted>());
m_AppliedTypes = new ComponentTypeSet(ComponentType.ReadWrite<Applied>(),
ComponentType.ReadWrite<Created>(),
ComponentType.ReadWrite<Updated>());
RequireForUpdate(m_UpdateQuery);
}
{{ Notes for modders: - AlignSystem is heavily integrated into the game's ECS and prefab/component conventions. To influence behavior, use or modify components such as Aligned, Aligned.m_SubObjectIndex, Attached, Owner, PrefabRef, PillarData, ObjectGeometryData, NetGeometryData, StackData, PlaceableObjectData, and related prefab subobject placeholders. - Be cautious when changing component layouts or marker components consumed/produced by this system: it assumes certain buffer/component availability and uses a command buffer to perform removals/PrefabRef changes. - The alignment work is Burst-compiled and runs as an IJob; any additional per-entity logic you add should be made job-friendly (use ComponentLookup/BufferLookup or modify components at main thread via a command buffer). - Terrain/Water readers are synchronized with job dependencies (m_TerrainSystem.AddCPUHeightReader / m_WaterSystem.AddSurfaceReader) — if you introduce additional systems that also read heights/surfaces, ensure you coordinate job dependencies similarly. }}