Grid & Placement¶
Coordinate model¶
Construction uses integer grid coordinates. The default cell size and story height are both one Unity unit:
Ground floor: Y = 0
Second floor: Y = 1
Third floor: Y = 2
StationRoomGrid.WorldToGrid converts world positions to grid coordinates. GridToLocalCenter returns the center of a cell, and ProjectToFloor places a world point on the current story's floor plane.
Piece kinds¶
Every ConstructionPieceDefinition has one of four kinds:
| Kind | Purpose | Examples |
|---|---|---|
Cell |
Structural floor/ceiling cell | Floor 1×1 |
Boundary |
Edge between two cells | Wall, Window, Door, Airlock |
Placeable |
Object occupying one or more cells | Bed, Locker, Generator |
WallAttachment |
Object attached to an existing boundary | Ventilator |
Boundaries are stored by an order-independent GridEdgeKey. Both sides of one shared edge therefore refer to the same wall or portal.
Footprints and rotation¶
Placeables support rectangular footprints. A 1×2 Bed covers two cells; a 2×2 Oxygen Generator covers four. Quarter-turn rotation swaps width and depth.
Placement validates every covered cell. It rejects a piece when:
- a required floor cell is missing;
- a blocking occupant already uses a covered cell;
- an object requiring an enclosed room would extend outside one room;
- an internal wall cuts through its footprint;
- a new boundary would slice through a multi-cell blocking object;
- a wall attachment has no supporting boundary;
- the selected prefab lacks its required runtime component.
Rejected placement is available through LastPlacementResult, events, the runtime feedback UI, and detailed Console diagnostics.
Placement controller¶
GridPlacementController owns preview, validation, placement, rotation, story selection, and removal. It does not read keyboard or mouse input itself.
Typical custom integration calls:
controller.SelectPiece(index);
controller.SetStory(story);
controller.RotateClockwise();
controller.UpdatePreview(cameraRay);
controller.TryPlacePreview(out GameObject placed);
controller.TryRemove(cameraRay, out GameObject removed);
RuntimePlacementInput is only a sample adapter for legacy mouse and keyboard input.
Safe demolition¶
A floor cannot be removed while:
- a placeable overlaps it;
- a boundary remains on one of its edges;
- a dependent wall attachment remains on a boundary.
Remove dependants first. This keeps the logical grid, room lookup, and save data consistent.
Multiple stories¶
CurrentStory selects the construction level. Each story uses the same X/Z grid with a different integer Y coordinate. The current worker pathfinder handles horizontal floor-cell paths; vertical worker connectors such as stairs or elevators are an extension point rather than an included feature.
Custom input¶
Input System actions, touch controls, gamepad cursors, UI Toolkit, multiplayer commands, and AI builders can call the controller's public API directly. Disable or remove RuntimePlacementInput when supplying a different adapter.