---
title: AFS_Core_Snapping
product: Advanced Framework Pro
version: 1.0
engine: Unreal Engine 5.8
updated: 2026-10-05
canonical: https://docs.human-codeable.com/plugins/afs-core-snapping.html
---

System

# AFS_Core_Snapping

Connector and anchor components with matrix-based snap transforms, surface alignment from a hit normal, anchor caching and ghost previews.

#### What it gives you

- Objects that snap into defined slots
- Surface snapping aligned to any hit normal
- Keyed connections through connector IDs
- Ghost preview while searching

#### Requires

None

#### Required by

None

9 assets60 API members

## Description

Snapping is expressed as a pair. A **connector** lives on the movable object and searches; an **anchor** lives on the target and accepts. The connector computes the transform that places itself exactly on the anchor, so the object arrives correctly oriented regardless of where it was grabbed.

`BPC_Connector_Anchor` matches against anchors by ID, which is how you build keyed connections — a battery that only fits its own slot. `BPC_Connector_Surface` instead traces for a surface and aligns to the hit normal, which is how you place objects on arbitrary walls and tables.

An anchor cache on the game state means connectors find candidates by ID lookup rather than by searching the level every frame.

## Setup

1. Enable `AFS_Core_Snapping`. Its `Engine.ini` enables Custom Depth-Stencil.
2. On the movable object, add `BPC_Connector_Anchor` or `BPC_Connector_Surface` and position it where the object should meet the target.
3. On the target, add `BPC_Anchor` and position it.
4. Set **Connector ID** on the connector and add it to the anchor's **Connector IDs To Allow**.

[![A connector on the object and an anchor on the target](../images/AFS_Core_Snapping_setup-1600.webp?v=329992bc)](../images/AFS_Core_Snapping_setup-1600.webp?v=329992bc)

A connector on the object and an anchor on the target

## Usage

### Keyed connections

Give the connector a **Connector ID** and list it in the anchor's allow list. Leave the allow list empty to accept anything.

### Surface placement

Use `BPC_Connector_Surface` and set **Rotate On Surface** to control whether the object keeps its rotation or aligns to the normal.

### Previewing

Turn on **Show Snapping Preview** for a ghost of the snapped result while the object is held, and **Show Anchors On Search** to reveal compatible anchors.

[![The battery held beside its slot, snap preview showing where it will land](../images/AFS_Core_Snapping_result-1600.webp?v=52694294)](../images/AFS_Core_Snapping_result-1600.webp?v=52694294)

The battery held beside its slot, snap preview showing where it will land

## Key properties

| Property | When to change |
|---|---|
| `Search Distance` | How near the object must be before a destination is offered |
| `Release Type` | Whether releasing snaps and attaches, snaps only, or does nothing |
| `Connector IDs To Allow` | To key an anchor to specific connectors |
| `Rotate On Surface` | Surface connectors: keep rotation, align to normal, or align and face player |
| `Wall Rotation Adjustment` | When the object's forward axis is not its natural facing |

## Extending

Derive from `BPC_Connector` and override `searchForAcceptableDestination` and `getDesiredRelativeTransform` for a new snapping rule.

## Multiplayer notes

Multiplayer

Attachment replicates through `Server_AttachConnectorToComponent` and its detach counterpart, so every client sees the same connection.

## Example map

`Map_Examples_Snapping` shows keyed anchor snapping with a battery and lightbulb, plus surface snapping.

## Troubleshooting

**Nothing snaps.** The connector ID is not in the anchor's allow list, or **Search Distance** is shorter than the gap.

**The object arrives rotated wrongly.** Adjust **Wall Rotation Adjustment**, or reposition the connector so its axes match the anchor's.

## API reference

Every blueprint asset in this plugin. Expand an asset to see its members.

### Components

**BPC_Anchor**13 members

extends `SceneComponent`

Fixed point on an actor that connectors may snap to. Add it wherever something should be attachable, list the connector IDs it accepts and set the sphere radius within which a connector can find it. It registers itself with the anchor cache at begin play, shows a hologram of the approaching actor while a connector is searching, and stops accepting once occupied.

| Kind | Name | Signature | Description |
|---|---|---|---|
| var | `Connector IDs to Allow`Settings | `name[]` | Connector IDs this anchor accepts. Leave empty to accept any connector; fill it in to build keyed connections such as a battery that only fits its own slot. |
| var | `Connector Should Attach`Settings | `bool` | Whether a connector physically attaches to this anchor, or merely snaps its transform without parenting. |
| var | `Sphere Radius`Settings | `float` | Radius within which a searching connector will consider this anchor. |
| fn | `IsAvailable`State | `() → bool` | Returns whether this anchor is currently free, meaning nothing is already attached to it. |
| fn | `getAnchorCache`Cache | `() → BPC_AnchorCache` | Returns the game-state anchor cache used to look anchors up by ID without searching the level. |
| fn | `IsConnectorAllowed`State | `(AnchorConnector: BPC_Connector_Anchor, out Allowed: bool)` | Returns whether the given connector is permitted by this anchor's allow list. |
| fn | `DrawDebug`Settings | `()` | Draws the anchor's search sphere in the world, for tuning placement. |
| event | `SetOccupyAnchor` | `(Set: bool)` | Marks the anchor as occupied or free, so other connectors skip it while it is in use. |
| event | `SetAttachedConnector` | `(Connector: BPC_Connector_Anchor, Set: bool)` | Records or clears the connector currently attached to this anchor. |
| event | `ConnectorSetSearching` | `(Set: bool, ConnectorAnchor: BPC_Connector_Anchor)` | Called when a connector starts or stops searching, so the anchor can show or hide its preview. |
| event | `CorrectListOfHelpers` | `()` | Reconciles the anchor's preview helper actors with the connectors currently searching. |
| event | `AnchorHovered` | `(ConnectorAnchor: BPC_Connector_Anchor)` | Called when a searching connector selects this anchor as its current best candidate, so it can highlight. |
| event | `OnDestroyed_Event` | `(DestroyedActor: Actor)` | Internal handler that removes this anchor from the cache when its owner is destroyed. |

**BPC_Connector**17 members

extends `SceneComponent`

Abstract base for the moving side of a snap: the component that searches for somewhere to attach to. Handles the replicated attachment, the attach and detach sounds, the hologram preview and the motion into place, and blocks the owner's interactions while it repositions. Its own search finds nothing, so add the anchor or surface variant, or subclass it and override the search.

| Kind | Name | Signature | Description |
|---|---|---|---|
| var | `Release Type`Settings | `E_Snap_AttachType` | What happens when the object is released near a valid destination: snap and attach, snap only, or nothing. |
| var | `Show Snapping Preview`Preview | `bool` | Whether a ghost preview of the snapped result is shown while searching. |
| var | `Sound Location Found`Sound | `SoundBase` | Sound played when a valid snap destination is first found. |
| var | `Sound Location Lost`Sound | `SoundBase` | Sound played when the connector loses its snap destination. |
| var | `Sound Detach`Sound | `SoundBase` | Sound played when the connector detaches from a destination. |
| var | `Sound Attach`Sound | `SoundBase` | Sound played when the connector attaches to a destination. |
| fn | `getSnapTransform`Transform | `(InWorldAnchorTransform: Transform, out OutWorldSnapTransform: Transform)` | Computes the world transform that places this connector exactly on the given anchor transform. |
| fn | `getAllActorsToIgnore`Trace | `(out ActorsToIgnore: Actor[])` | Returns actors excluded from the destination search, normally the carried object and the player. |
| fn | `searchForAcceptableDestination`Trace | `(out ComponentToAttachTo: SceneComponent, out DesiredDestination: Transform, out Priority: float, out SocketToAttachTo: name)` | Looks for the best snap destination within search distance and returns it with a priority score. Override to implement a new snapping rule. |
| fn | `getDesiredRelativeTransform`Transform | `() → Transform` | Returns the transform the owning actor should take relative to the destination. Override in a subclass to change how the object aligns. |
| event | `AttachConnectorToComponent` | `(Transform: Transform, Component: SceneComponent, SocketName: name, AllowMotion: bool)` | Attaches the owning actor to the target component at the given transform and socket. |
| event | `DetachConnectorFromActor` | `()` | Detaches the owning actor from whatever it is currently snapped to. |
| event | `PositionToRelativeTransform` | `(Transform: Transform, TargetSceneComponent: SceneComponent, TargetSocket: name, UseMotion: bool)` | Moves the owning actor to the given relative transform, optionally animating the movement rather than snapping instantly. |
| event | `Server_AttachConnectorToComponent` | `(RelativeTransform: Transform, Component: SceneComponent, SocketName: name, AllowMotion: bool)` | Replicated attach, so every client sees the object snapped to the same destination. |
| event | `Server_DetachConnectorFromActor` | `()` | Clears this connector's stored connection on the server, which replicates the break out to every client. Called by Detach Connector From Actor; the detach sound is played locally by the caller, so calling this on its own breaks the link silently. |
| event | `ConnectorFoundDesiredLocation` | `(Transform: Transform, ComponentToAttachTo: SceneComponent)` | Fires when a valid destination is found, carrying the transform and target component. Bind to it to drive custom preview visuals. |
| event | `SetSearch` | `(Search: bool)` | Starts or stops searching for a destination. Normally driven by the grip system when the object is picked up and released. |

**BPC_Connector_Anchor**12 members

extends `BPC_Connector`

Connector that snaps to prepared anchor points. It asks the anchor cache for every anchor registered under its Connector ID, takes the nearest one inside that anchor's radius, and priority rises the closer it gets. Add it to an actor that should click into place at known positions and set the ID to match the anchors you want it to accept.

| Kind | Name | Signature | Description |
|---|---|---|---|
| var | `Connector ID`Settings | `name` | Identifier matched against an anchor's allow list. Use it to make a connector fit only certain anchors. |
| var | `Show Anchors on Search`Anchors | `bool` | Whether compatible anchors reveal themselves while this connector is searching, so the player can see where the object fits. |
| var | `Initial Connection`Initial | `Struct_Connector_Startup_Anchor` | An anchor to be connected to at begin play, given as an actor and the tag of the anchor component on it. On the server only, the first anchor on that actor carrying the tag is attached to as though it had been snapped there by hand. Leave the actor empty and the connector starts loose. This is how a level can be laid out already assembled instead of snapping itself together in the first frame. |
| fn | `getDesiredWorldTransformForAnchor` | `(Anchor: BPC_Anchor) → Transform` | Returns the world transform the owner would have to end up with to sit on the given anchor, by running that anchor's world transform through the connector's snap transform. Use it to preview or measure a connection without making one. |
| fn | `getAnchorCaches` | `() → BPC_AnchorCache` | Returns the anchor cache held on the game state, adding it the first time it is asked for. Every connector shares that one cache, which is how a connector finds candidate anchors without searching the level. |
| fn | `searchForAcceptableDestination`Trace | `(out ComponentToAttachTo: SceneComponent, out DesiredDestination: Transform, out Priority: float, out SocketToAttachTo: name)` | Looks for the best snap destination within search distance and returns it with a priority score. Override to implement a new snapping rule. |
| event | `OnConnectorAttached_Event` | `(Connector: BPC_Connector, AttachedToComponent: SceneComponent)` | Internal handler that marks the target anchor occupied once attachment completes. |
| event | `OnConnectorDetached_Event` | `(Connector: BPC_Connector, DetachedFromComponent: SceneComponent)` | Internal handler that frees the anchor when the connector detaches. |
| event | `PositionToRelativeTransform` | `(Transform: Transform, TargetSceneComponent: SceneComponent, TargetSocket: name, UseMotion: bool)` | Moves the owner onto the anchor, animating when requested. |
| event | `AttachConnectorToAnchor` | `(Anchor: BPC_Anchor, AllowMotion: bool)` | Attaches this connector to a specific anchor, bypassing the search. |
| event | `ConnectorFoundDesiredLocation` | `(Transform: Transform, ComponentToAttachTo: SceneComponent)` | Fires when a compatible anchor is found. |
| event | `SetSearch` | `(Search: bool)` | Starts or stops the anchor search, revealing compatible anchors when configured to. |

**BPC_Connector_Surface**6 members

extends `BPC_Connector`

Connector that snaps to whatever surface it is traced against rather than to a prepared anchor. Accepts hits up to sixty degrees off, optionally only on components carrying the required tag, and can align the owner to the surface normal with a rotation adjustment for meshes that do not face along X. Add it to shelves, ceiling lights and anything placed against walls or floors.

| Kind | Name | Signature | Description |
|---|---|---|---|
| var | `Requires Tag`Settings | `name` | Actor tag a surface must carry to accept this connector. Leave empty to allow any surface. |
| var | `Initial Connection`Initial | `Struct_Connector_Startup_Surface` | A surface to be sitting on at begin play, given as an actor and the tag of a scene component on it. On the server only, the connector attaches to the first tagged component on that actor, or to the actor's root component when no tag matches, keeping the owner's own transform. Leave the actor empty and the connector starts loose. |
| fn | `alignRotationToNormal`Transform | `(InNormal: Vector, InRotation: Rotator, out OutRotation: Rotator)` | Rotates a rotator so its up axis matches the given surface normal while preserving its facing as closely as possible. |
| fn | `getSurfaceTransform`Transform | `(InHitPoint: Vector, InNormal: Vector, out OutTransform: Transform)` | Computes the world transform that seats this connector on a surface at the given hit point and normal. |
| fn | `getDesiredRelativeTransform`Transform | `() → Transform` | Returns the transform the owning actor should take relative to the destination. Override in a subclass to change how the object aligns. |
| fn | `searchForAcceptableDestination`Trace | `(out ComponentToAttachTo: SceneComponent, out DesiredDestination: Transform, out Priority: float, out SocketToAttachTo: name)` | Looks for the best snap destination within search distance and returns it with a priority score. Override to implement a new snapping rule. |

### Helper

**BPC_AnchorCache**4 members

extends `ActorComponent`

Registry of every snapping anchor in the world, keyed by connector ID and held on the game state, so a searching connector never has to sweep the level. Anchors add and remove themselves as they begin play and are destroyed. It is added to the game state automatically the first time an anchor or connector asks for it, so there is nothing to place or configure.

| Kind | Name | Signature | Description |
|---|---|---|---|
| fn | `getSnapLocationHelper`Snap Helper | `() → BP_Helper_SnapLocation` | Returns the shared helper actor used to visualise snap locations. |
| fn | `getAllAnchorsForID`Cache | `(ID: name, out Anchors: BPC_Anchor[])` | Returns every cached anchor registered under the given ID. |
| fn | `RemoveAnchorFromCache`Cache | `(ID: name, Anchor: BPC_Anchor)` | Takes an anchor out of the list registered under the given identifier, so connectors stop offering it as a snap target. Anchors call this themselves when they are deactivated or destroyed. |
| fn | `AddAnchorToCache`Cache | `(ID: name, Anchor: BPC_Anchor)` | Registers an anchor under an ID so connectors can find it without searching the level. |

**BP_Helper_MeshCopy_Anchor**4 members

extends `BP_Helper_MeshCopy`

Hologram copy of the connecting actor's meshes, shown at an available anchor while a connector is searching so the player can see where it would go. Tints briefly to the hovered colour when the connector passes over that anchor. Spawned and destroyed by the anchor, not placed by hand.

| Kind | Name | Signature | Description |
|---|---|---|---|
| var | `Sphere Radius`Settings | `float` | Radius of the anchor indicator sphere. |
| var | `Anchor` | `BPC_Anchor` | The anchor this preview represents. |
| var | `Color Hovered`Style | `LinearColor` | Colour used when this anchor is the connector's current best candidate. |
| event | `AnchorHovered` | `()` | Switches the preview to its hovered colour. |

**BP_Helper_MeshCopy_Preview**0 members

extends `BP_Helper_MeshCopy`

Hologram preview of the owner's meshes shown at the place a connector has decided it would snap to. It adds nothing to the mesh copy helper it inherits from, and the connector spawns and moves it for you; subclass it to change how the preview looks.

No editor-visible members; this asset configures defaults only.

**BP_Helper_SnapLocation**0 members

extends `Actor`

Bare marker actor the snapping system spawns to hold a destination transform while a connector works out where to go. Empty apart from auto-destroy, with nothing to configure; the anchor cache keeps one and hands it out.

No editor-visible members; this asset configures defaults only.

### Libraries

**FL_Snapping**4 members

extends `BlueprintFunctionLibrary`

Function library exposing the snapping maths on its own: the transform that would put a connector on a given anchor or surface point, and the rotation that aligns a component to a surface normal. Call these statically when placement has to be worked out away from a live connector, in an editor tool or a preview of your own.

| Kind | Name | Signature | Description |
|---|---|---|---|
| fn | `AlignRotationToNormal` | `(InNormal: Vector, InRotation: Rotator, __WorldContext: Object, out OutRotation: Rotator)` | Rotates a rotator so its up axis matches a surface normal while preserving its facing as closely as possible. |
| fn | `GetAnchorTransform` | `(InConnector: BPC_Connector, InAnchor: BPC_Anchor, __WorldContext: Object, out OutTransform: Transform)` | Returns the world transform that places a connector on the given anchor component. |
| fn | `GetSurfaceTransform` | `(InConnectorSurface: BPC_Connector_Surface, InNormal: Vector, InHitPoint: Vector, __WorldContext: Object, out OutTransform: Transform)` | Returns the world transform that seats a surface connector on a surface at the given hit point and normal. |
| fn | `GetSnapTransform` | `(InConnector: BPC_Connector, InWorldAnchorTransform: Transform, __WorldContext: Object, out OutTransform: Transform)` | Returns the world transform that places a connector exactly on the given anchor transform. |
