Snap-category metadata for 3D placeables ( draft surface). Declares what a placeable IS ([member family]) and what it may attach to ([member snaps_with]). Matching is a directional accept-list: the entry being placed checks its own [member snaps_with] against the [member family] of already-placed neighbors. Families are arbitrary [StringName]s, so the granularity ("building", "floor", "wall_exterior", ...) is the game's choice — the plugin only provides the matching contract. See addons/grid_placement/guides/3d-object-placement.md for the design rationale (why accept-lists instead of mutual type equality). Runtime-instantiated: assigned on ScenePlacementEntry.snap_profile_3d and read by ObjectPlacementService3D. Do not mark @tool.
Source: addons/grid_placement/placement/placeable/placement_snap_profile_3d.gd
Syntax
class PlacementSnapProfile3D extends ResourceMembers
| Name | Kind | Summary |
|---|---|---|
snap_mode | Property | How this placeable attaches to the grid: - CELL: occupies whole columns; adjacency is checked against orthogonal neighbor columns (foundations, floors, furniture). Set [member occupy_columns] false for stacked overlays (roofs, gable ends) that sit on an already-built footprint. - EDGE: mounts on one of the four edges of a HOST cell (thin modular pieces like wall panels/fences). [member snaps_with] then names the families that may host it, and the piece is auto-rotated to run along the edge it snaps to. - FACE: mounts onto a registered vertical face at [member mount_height] (wall-hung pieces like paintings, shelves, sconces). The face normal determines yaw; pitch/roll are intentionally out of scope. - CORNER: mounts on one of the four XZ intersections of a HOST cell (structural corner posts). Occupancy is the canonical intersection key, not the cell centroid; yaw is derived from the two axes of that corner. Optional SMOOTH world-space sockets (bit flags). GRID [enum SnapMode] is unchanged. NONE = 0, ENDS = 1, PERIMETER = 2, FACE = 4, UP = 8. Attachment mode for this placeable. See [enum SnapMode]. |
attachment_requirement | Property | How strictly this entry must attach to a compatible provider. INHERIT defers to ObjectPlacementSettings3D.default_attachment_requirement, except that the legacy require_adjacent_snap=true still resolves REQUIRED so existing serialized profiles keep their behavior bit-for-bit. CORNER-only host-count policy, consulted only when CORNER attachment is REQUIRED. ANY_ONE accepts a single compatible host touching the intersection; TWO_ORTHOGONAL keeps the strict two-perpendicular-hosts contract. Zero-host CORNER placement is attachment OPTIONAL, not a topology value. Per-entry attachment override. INHERIT (default) uses the settings default; set explicitly on new profiles instead of require_adjacent_snap. |
corner_host_topology | Property | Per-entry CORNER topology override. INHERIT (default) uses the settings default; consulted only for REQUIRED CORNER attachment. |
occupy_columns | Property | CELL only. When true (default), the footprint reserves grid columns and conflicts with other CELL occupants. When false, preview/commit still run the GRID CELL path (ghost, adjacency, ground) but do not reserve or collide with column occupancy — for second-story overlays such as roofs. |
mount_height | Property | FACE-mode vertical band above the provider surface. Band 0 is the provider surface itself; each next band rises by one GridMap cell height. |
provides_mount_faces | Property | CELL-mode providers with rectangular footprints expose their perimeter vertical faces as mount sockets for FACE-mode consumers. |
family | Property | Category this placeable belongs to (what neighbors will test against). |
snaps_with | Property | Families this placeable may snap/attach to. Order does not matter. |
require_adjacent_snap | Property | When true, placement is only valid if at least one orthogonally adjacent cell holds an object whose family is in [member snaps_with]. When false, the profile is advisory (free placement; family still recorded so other objects can snap to this one). Deprecated: kept serialized so existing profiles resolve identically, but validators no longer read this — they read the resolved [enum AttachmentRequirement] policy instead. Do not set on new profiles; use [member attachment_requirement] explicitly. |
resolve_attachment | Method | |
resolve_corner_topology | Method | |
requires_attachment | Method | |
seam_close_to_partner | Property | GRID CELL seam closure: when true and adjacency finds a compatible partner, the committed origin shifts toward that partner so the mesh face nearest the partner lands exactly on the shared grid line. Default false = pure footprint-centroid (existing behavior bit-for-bit). Needs ScenePlacementEntry.seam_bounds_3d (mesh truth); without it, no-op. Symmetric meshes centered on origin yield shift zero even when enabled. |
smooth_sockets | Property | SMOOTH-only: which world sockets this placeable publishes after commit. Combine flags (e.g. PERIMETER | UP for a floor). Default NONE = free SMOOTH. |
smooth_snap_radius | Property | World-unit radius for consuming a published socket. 0 disables snap (free pose). |
smooth_socket_extent | Property | Half-length (ENDS) or half-side (PERIMETER) in world units. |
face_mount_anchor | Property | Node name of the optional declared mount anchor on a FACE-mode consumer scene: a Node3D child whose origin is the point that must land exactly on the provider's [member ObjectPlacementGeometry3D.FACE_SOCKET_NODE_NAME] plane (and whose -Z matches the socket's outward -Z). When both sides declare, the service composes the exact mate transform — flush by construction instead of a cell-derived offset guess. |
face_socket_symmetric | Property | Explicit rotational-symmetry opt-in for FACE socket derivation. When true, the provider's mesh is symmetric about its vertical axis, so the canonical FaceSocket may be yaw-rotated onto any face with no authored socket. NEVER inferred: asymmetric meshes (e.g. a rectangular wall) have different face-plane distances per side, and inferred derivation mates consumers inside the mesh. Leave false unless the mesh is truly symmetric. |
accepts_family | Method | |
provides_smooth_role | Method | |
consume_smooth_roles | Method |