This guide explains how targeting works in Grid Placement 6.0.0.
Version note: This guide is for the 2D
TileMapLayerplacement path in Grid Placement 6.0.0.
Main Pieces
| Piece | What it does |
|---|---|
GridPositioner2D |
Tracks the cursor/controller target cell and snaps to the grid. |
TargetingShapeCast2D |
Detects targetable objects for move/demolish/highlight workflows. |
GridTargetingState |
Stores the active target map, positioner, target object, and targeting flags. |
TargetHighlighter |
Optional visual feedback for the currently targeted object. |
GridPlacementHost |
Reads the active session/targeting state while dispatching placement input. |
GridPositioner2D
GridPositioner2D handles the visible grid cursor/target position.
It is responsible for:
- Mouse follow: tracking the cursor and snapping to tile centers.
- Keyboard/controller movement when configured.
- Recenter behavior when entering placement modes.
- Visibility logic based on mode, settings, and UI/input state.
It does not own shapecast collision detection or rotation/flip behavior.
TargetingShapeCast2D
TargetingShapeCast2D is the collision-query layer. Its job is to update GridTargetingState.target from the current physics collision result.
- If
GridTargetingState.is_manual_targeting_activeis true, automatic target updates are skipped. - When a collider is found, the shape cast resolves the targetable root when possible.
- When no collider is found, the current target is cleared.
Use this for object targeting, not for deciding whether a new object placement is valid. Placement validity belongs to placement rules.
GridTargetingState
The targeting state is the shared resource other systems consume.
Common fields:
var target: Node2D
var target_map: TileMapLayer
var maps: Array[TileMapLayer]
var positioner: Node2D
var is_manual_targeting_active: bool
PlacementLevelContext normally assigns target_map, and GridPositioner2D registers itself as the positioner.
Processing Flow
User input
→ GridPositioner2D moves to snapped tile center
→ TargetingShapeCast2D queries physics collisions at that center
→ GridTargetingState.target updates with the found object, if any
→ placement, manipulation, or UI reads the targeting state
Essential Setup for Plugin Users
If targeting looks broken, check these first:
PlacementLevelContext.target_mapis assigned.GridPositioner2Dwas injected or registered successfully.TargetingShapeCast2Dwas injected or registered successfully.- Your shapecast collision mask matches the targetable layers.
- The mode/settings allow the positioner to stay active/visible.
- Your UI is not consuming the input path you expect.
Collision Layer vs Collision Mask for Targeting
TargetingShapeCast2D uses Godot's collision system to detect objects.
| Property | What it means | Used by ShapeCast2D to... |
|---|---|---|
collision_mask on TargetingShapeCast2D |
Which layers to check | Find objects. |
collision_layer on target objects |
Which layers the object is on | Be detectable by matching masks. |
Detection works only when the shapecast mask overlaps the target object's layer.
TargetingShapeCast2D:
collision_mask: includes layer 10
Placed object:
collision_layer: includes layer 10
Common mistake: setting only collision_mask = 10 on placed objects. That lets the object detect layer 10 things, but it does not put the object on layer 10. The shapecast cannot find it unless the object's collision_layer includes the target layer.
Avoid Duplicate Targeting Layers
Only the intended target/root should own the targeting layer.
# Good: one clear target owner
GeyserPumpRoot:
collision_layer: includes target layer
StaticBody2D:
collision_layer: does not include target layer
# Risky: multiple target owners
GeyserPumpRoot:
collision_layer: includes target layer
StaticBody2D:
collision_layer: also includes target layer
When multiple nodes in one scene have the targeting layer, the shapecast may report a child collider instead of the root you intended.
ShapeCast Collision Flags
Godot ShapeCast2D collision flags matter.
TargetingShapeCast2D:
collide_with_areas: true
collide_with_bodies: true
Use collide_with_areas = true when your target objects are Area2D. Use collide_with_bodies = true when your target objects are StaticBody2D or other physics bodies. Many placed objects use bodies, so leaving collide_with_bodies false is a common cause of move/demolish/highlight failing.
Quick diagnostic:
print("TargetingShapeCast2D: areas=%s, bodies=%s" % [
$TargetingShapeCast2D.collide_with_areas,
$TargetingShapeCast2D.collide_with_bodies
])
TargetingShapeCast2D.debug_log_collisions can also be enabled for verbose collision logging when a logger is available.
Preview Stability and Manual Targeting
During active building/manipulation flows:
TargetingShapeCast2Dcan stop auto-updating when manual targeting is active.- Collision exclusions can prevent previews from blocking their own placement validation.
- Manipulation visuals are handled by
ManipulationParent, not the positioner.
Common Targeting Problems
- Positioner never appears
- Check mode/state injection.
- Check targeting settings visibility rules.
- Target object never updates / move-demolish-highlight does not work
- Check
collide_with_areasandcollide_with_bodiesfirst. - Check
TargetingShapeCast2D.collision_maskmatches your targeting layer. - Check that the target object has
collision_layerincluding that same layer. - Enable
TargetingShapeCast2D.debug_log_collisionsfor diagnostics.
- Check
- Cursor does not move
- Check
GridPositioner2Dinput settings and target map wiring.
- Check
- Move/build targeting acts frozen
- Check whether manual targeting is intentionally active.
Related Guides
Source
docs/v6-0/guides/targeting-flow.md
Plugin docs root:gdscript/plugins/grid_placement_dev/docs