Targeting Flow (5.0.3)
This guide explains how targeting works in 5.0.3, including the relationship between GridTargetingSystem, GridPositioner2D, TargetingShapeCast2D, and GridTargetingState.
Use Getting Started (5.0.3) first if you are wiring a new project. The setup guide places the addon, templates, and scene nodes; this page only describes the runtime targeting contract after that wiring exists.
Core Targeting Components
| Component | Purpose |
|---|---|
| GridTargetingSystem | Central targeting-side coordinator for targeting state/settings/path manager validation |
| GridPositioner2D | Owns mouse/keyboard input for cursor-to-grid positioning |
| TargetingShapeCast2D | ShapeCast2D that updates GridTargetingState.target from collisions |
| GridTargetingState | Holds target object, tilemap references, positioner, target map, and manual targeting flags |
Input Ownership
In the current 5.0.3 runtime, GridPositioner2D owns the main cursor/grid input handling. It:
- receives input events
- converts screen coordinates into world coordinates
- converts world coordinates into target tiles
- moves itself to the active tile center
- updates visibility based on mode/settings/input state
GridTargetingSystem still matters, but it is not the node that directly owns mouse-follow behavior.
TargetingShapeCast2D
TargetingShapeCast2D is the collision-query layer. Its job is to update GridTargetingState.target from the current shapecast result.
- if
GridTargetingState.is_manual_targeting_activeis true, automatic target updates are skipped - when a collider is found, the raw collider may be promoted to a targetable root
Area2D - when no collider is found, the current target is cleared
GridPositioner2D
GridPositioner2D is responsible for:
- mouse movement
- keyboard tile movement
- recenter behavior
- visibility behavior
- assigning itself into
GridTargetingState.positioner
It does not own:
- shapecast collision targeting
- rotation/flip behavior
- manipulation transforms
Target Highlighting
TargetHighlighter is the visual feedback layer for targeting. It does not move the cursor or decide which object is targetable. Its job is to read the current targeting result and highlight the target so players can see what the placement or manipulation flow is acting on.
Use it when you want feedback for:
- build mode selection
- move-mode target hover
- demolish or inspect previews
Practical guidance:
- keep highlighting separate from cursor movement so targeting stays easy to reason about
- wire the highlighter as a visual/UI concern, not as the source of targeting truth
- if highlighting looks wrong, check the targetable object setup and the visual settings used by the highlighter
GridTargetingState
The targeting state is the shared contract other systems consume. In practice it includes references such as:
Processing Flow
Recenter and visibility behavior
GridPositioner2D also owns several user-visible behaviors:
- recenter on enable
- manual recenter action
- visibility changes when mode changes
- hide/show behavior based on input and targeting settings
- OFF-mode gating via
remain_active_in_off_mode
Essential setup for plugin users
If targeting looks broken, check these first:
GBLevelContext.target_mapis assignedGridPositioner2Dwas injected successfullyTargetingShapeCast2Dwas injected successfully- your shapecast collision mask matches the targetable layers
- the mode allows the positioner to stay active/visible
- your UI is not consuming the input path you expect
Preview stability and manual targeting
During active building/manipulation flows:
TargetingShapeCast2Dintentionally stops auto-updating when manual targeting is active- collision exclusions can be applied so previews do not block 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
- check
TargetingShapeCast2D.collision_mask - check that the targetable object is actually collidable
- 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