Table of Contents

Class Cursor2D

Namespace
MoonBark.GridPlacement.Godot.Cursor
Assembly
MoonBark.GridPlacement.Godot.dll

Godot Node2D that tracks the cursor position on a grid and forwards input to the IPlacementInputBridge entirely through configurable Input Map actions.

All input is driven by CursorInputSettings actions — no hardcoded mouse buttons or keycodes.

Input action contract

  • ConfirmAction (press & hold) Press → start drag + SetDragActive(true). Hold + move → auto-place on each tile change. Release → SetDragActive(false).
  • ConfirmAction (tap) Tap (press & release without moving) → emit ConfirmPressed. PlacementInputController routes this to ExecutePlacement().
  • CancelAction Emit CancelPressed. Routed by PlacementInputController to CancelPlacement().
  • Directional actions (Up/Down/Left/Right) Move cursor one tile per press, with repeat when held.

Drag-to-place flow (press & hold confirm)

Press ConfirmAction
  → SetDragActive(true)
  → Move to new tile
  → _Process() detects tile change
  → Emit GridPositionChanged(gridPos)
  → Auto-calls ExecutePlacement() for each new tile
  → Repeat move → auto-place while held
Release ConfirmAction
  → SetDragActive(false)

Tap-to-place flow

Tap ConfirmAction (no movement between press and release)
  → Emit ConfirmPressed
  → PlacementInputController calls ExecutePlacement()
[ScriptPath("res://addons/grid_placement/cursor/Cursor2D.cs")]
public class Cursor2D : Node2D, IDisposable
Inheritance
GodotObject
Node
CanvasItem
Node2D
Cursor2D
Implements
Inherited Members
Node2D.Translate(Vector2)
Node2D.GlobalTranslate(Vector2)
Node2D.ApplyScale(Vector2)
Node2D.LookAt(Vector2)
Node2D.GetAngleTo(Vector2)
Node2D.ToLocal(Vector2)
Node2D.ToGlobal(Vector2)
Node2D.GetRelativeTransformToParent(Node)
Node2D.InvokeGodotClassMethod(in godot_string_name, NativeVariantPtrArgs, out godot_variant)
Node2D.HasGodotClassMethod(in godot_string_name)
Node2D.HasGodotClassSignal(in godot_string_name)
Node2D.Position
Node2D.Rotation
Node2D.RotationDegrees
Node2D.Scale
Node2D.Skew
Node2D.Transform
Node2D.GlobalPosition
Node2D.GlobalRotation
Node2D.GlobalRotationDegrees
Node2D.GlobalScale
Node2D.GlobalSkew
Node2D.GlobalTransform
CanvasItem.NotificationTransformChanged
CanvasItem.NotificationLocalTransformChanged
CanvasItem.NotificationDraw
CanvasItem.NotificationVisibilityChanged
CanvasItem.NotificationEnterCanvas
CanvasItem.NotificationExitCanvas
CanvasItem.NotificationWorld2DChanged
CanvasItem._Draw()
CanvasItem.GetCanvasItem()
CanvasItem.IsVisibleInTree()
CanvasItem.Show()
CanvasItem.Hide()
CanvasItem.QueueRedraw()
CanvasItem.MoveToFront()
CanvasItem.DrawTexture(Texture2D, Vector2, Color?)
CanvasItem.DrawLcdTextureRectRegion(Texture2D, Rect2, Rect2, Color?)
CanvasItem.DrawStyleBox(StyleBox, Rect2)
CanvasItem.DrawPrimitive(Vector2[], Color[], Vector2[], Texture2D)
CanvasItem.DrawPolygon(Vector2[], Color[], Vector2[], Texture2D)
CanvasItem.DrawColoredPolygon(Vector2[], Color, Vector2[], Texture2D)
CanvasItem.DrawMesh(Mesh, Texture2D, Transform2D?, Color?)
CanvasItem.DrawMultimesh(MultiMesh, Texture2D)
CanvasItem.DrawSetTransformMatrix(Transform2D)
CanvasItem.DrawEndAnimation()
CanvasItem.GetTransform()
CanvasItem.GetGlobalTransform()
CanvasItem.GetGlobalTransformWithCanvas()
CanvasItem.GetViewportTransform()
CanvasItem.GetViewportRect()
CanvasItem.GetCanvasTransform()
CanvasItem.GetScreenTransform()
CanvasItem.GetLocalMousePosition()
CanvasItem.GetGlobalMousePosition()
CanvasItem.GetCanvas()
CanvasItem.GetCanvasLayerNode()
CanvasItem.GetWorld2D()
CanvasItem.SetInstanceShaderParameter(StringName, Variant)
CanvasItem.GetInstanceShaderParameter(StringName)
CanvasItem.IsLocalTransformNotificationEnabled()
CanvasItem.IsTransformNotificationEnabled()
CanvasItem.ForceUpdateTransform()
CanvasItem.MakeCanvasPositionLocal(Vector2)
CanvasItem.MakeInputLocal(InputEvent)
CanvasItem.EmitSignalDraw()
CanvasItem.EmitSignalVisibilityChanged()
CanvasItem.EmitSignalHidden()
CanvasItem.EmitSignalItemRectChanged()
CanvasItem.Visible
CanvasItem.Modulate
CanvasItem.SelfModulate
CanvasItem.ShowBehindParent
CanvasItem.TopLevel
CanvasItem.ClipChildren
CanvasItem.LightMask
CanvasItem.VisibilityLayer
CanvasItem.ZIndex
CanvasItem.ZAsRelative
CanvasItem.YSortEnabled
CanvasItem.TextureFilter
CanvasItem.TextureRepeat
CanvasItem.Material
CanvasItem.UseParentMaterial
CanvasItem.Draw
CanvasItem.VisibilityChanged
CanvasItem.Hidden
CanvasItem.ItemRectChanged
Node.NotificationEnterTree
Node.NotificationExitTree
Node.NotificationMovedInParent
Node.NotificationReady
Node.NotificationPaused
Node.NotificationUnpaused
Node.NotificationPhysicsProcess
Node.NotificationProcess
Node.NotificationParented
Node.NotificationUnparented
Node.NotificationSceneInstantiated
Node.NotificationDragBegin
Node.NotificationDragEnd
Node.NotificationPathRenamed
Node.NotificationChildOrderChanged
Node.NotificationInternalProcess
Node.NotificationInternalPhysicsProcess
Node.NotificationPostEnterTree
Node.NotificationDisabled
Node.NotificationEnabled
Node.NotificationResetPhysicsInterpolation
Node.NotificationEditorPreSave
Node.NotificationEditorPostSave
Node.NotificationWMMouseEnter
Node.NotificationWMMouseExit
Node.NotificationWMWindowFocusIn
Node.NotificationWMWindowFocusOut
Node.NotificationWMCloseRequest
Node.NotificationWMGoBackRequest
Node.NotificationWMSizeChanged
Node.NotificationWMDpiChange
Node.NotificationVpMouseEnter
Node.NotificationVpMouseExit
Node.NotificationWMPositionChanged
Node.NotificationOsMemoryWarning
Node.NotificationTranslationChanged
Node.NotificationWMAbout
Node.NotificationCrash
Node.NotificationOsImeUpdate
Node.NotificationApplicationResumed
Node.NotificationApplicationPaused
Node.NotificationApplicationFocusIn
Node.NotificationApplicationFocusOut
Node.NotificationTextServerChanged
Node.GetNode<T>(NodePath)
Node.GetNodeOrNull<T>(NodePath)
Node.GetOwner<T>()
Node.GetOwnerOrNull<T>()
Node.GetParent<T>()
Node.GetParentOrNull<T>()
Node._EnterTree()
Node._GetConfigurationWarnings()
Node._Input(InputEvent)
Node._ShortcutInput(InputEvent)
Node._UnhandledInput(InputEvent)
Node._UnhandledKeyInput(InputEvent)
Node.PrintOrphanNodes()
Node.RemoveChild(Node)
Node.HasNode(NodePath)
Node.GetNode(NodePath)
Node.GetNodeOrNull(NodePath)
Node.GetParent()
Node.HasNodeAndResource(NodePath)
Node.GetNodeAndResource(NodePath)
Node.IsInsideTree()
Node.IsPartOfEditedScene()
Node.IsAncestorOf(Node)
Node.IsGreaterThan(Node)
Node.GetPath()
Node.RemoveFromGroup(StringName)
Node.IsInGroup(StringName)
Node.GetGroups()
Node.PrintTree()
Node.PrintTreePretty()
Node.GetTreeString()
Node.GetTreeStringPretty()
Node.GetPhysicsProcessDeltaTime()
Node.IsPhysicsProcessing()
Node.GetProcessDeltaTime()
Node.IsProcessing()
Node.IsProcessingInput()
Node.IsProcessingShortcutInput()
Node.IsProcessingUnhandledInput()
Node.IsProcessingUnhandledKeyInput()
Node.CanProcess()
Node.IsDisplayedFolded()
Node.IsProcessingInternal()
Node.IsPhysicsProcessingInternal()
Node.IsPhysicsInterpolated()
Node.IsPhysicsInterpolatedAndEnabled()
Node.ResetPhysicsInterpolation()
Node.SetTranslationDomainInherited()
Node.GetWindow()
Node.GetLastExclusiveWindow()
Node.GetTree()
Node.CreateTween()
Node.GetSceneInstanceLoadPlaceholder()
Node.IsEditableInstance(Node)
Node.GetViewport()
Node.QueueFree()
Node.RequestReady()
Node.IsNodeReady()
Node.GetMultiplayerAuthority()
Node.IsMultiplayerAuthority()
Node.RpcConfig(StringName, Variant)
Node.GetRpcConfig()
Node.Rpc(StringName, params Variant[])
Node.UpdateConfigurationWarnings()
Node.CallDeferredThreadGroup(StringName, params Variant[])
Node.SetDeferredThreadGroup(StringName, Variant)
Node.CallThreadSafe(StringName, params Variant[])
Node.SetThreadSafe(StringName, Variant)
Node.EmitSignalReady()
Node.EmitSignalRenamed()
Node.EmitSignalTreeEntered()
Node.EmitSignalTreeExiting()
Node.EmitSignalTreeExited()
Node.EmitSignalChildEnteredTree(Node)
Node.EmitSignalChildExitingTree(Node)
Node.EmitSignalChildOrderChanged()
Node.EmitSignalReplacingBy(Node)
Node.EmitSignalEditorDescriptionChanged(Node)
Node.EmitSignalEditorStateChanged()
Node.Name
Node.UniqueNameInOwner
Node.SceneFilePath
Node.Owner
Node.Multiplayer
Node.ProcessMode
Node.ProcessPriority
Node.ProcessPhysicsPriority
Node.ProcessThreadGroup
Node.ProcessThreadGroupOrder
Node.ProcessThreadMessages
Node.PhysicsInterpolationMode
Node.AutoTranslateMode
Node.EditorDescription
Node.Ready
Node.Renamed
Node.TreeEntered
Node.TreeExiting
Node.TreeExited
Node.ChildEnteredTree
Node.ChildExitingTree
Node.ChildOrderChanged
Node.ReplacingBy
Node.EditorDescriptionChanged
Node.EditorStateChanged
GodotObject.NotificationPostinitialize
GodotObject.NotificationPredelete
GodotObject.NotificationExtensionReloaded
GodotObject.IsInstanceValid(GodotObject)
GodotObject.WeakRef(GodotObject)
GodotObject.Dispose()
GodotObject.ToString()
GodotObject.ToSignal(GodotObject, StringName)
GodotObject._Get(StringName)
GodotObject._GetPropertyList()
GodotObject._IterGet(Variant)
GodotObject._IterInit(Array)
GodotObject._IterNext(Array)
GodotObject._PropertyCanRevert(StringName)
GodotObject._PropertyGetRevert(StringName)
GodotObject._Set(StringName, Variant)
GodotObject._ValidateProperty(Dictionary)
GodotObject.Free()
GodotObject.GetClass()
GodotObject.Set(StringName, Variant)
GodotObject.Get(StringName)
GodotObject.SetIndexed(NodePath, Variant)
GodotObject.GetIndexed(NodePath)
GodotObject.GetPropertyList()
GodotObject.GetMethodList()
GodotObject.PropertyCanRevert(StringName)
GodotObject.PropertyGetRevert(StringName)
GodotObject.GetInstanceId()
GodotObject.SetScript(Variant)
GodotObject.GetScript()
GodotObject.SetMeta(StringName, Variant)
GodotObject.RemoveMeta(StringName)
GodotObject.GetMeta(StringName, Variant)
GodotObject.HasMeta(StringName)
GodotObject.GetMetaList()
GodotObject.HasUserSignal(StringName)
GodotObject.RemoveUserSignal(StringName)
GodotObject.EmitSignal(StringName, params Variant[])
GodotObject.Call(StringName, params Variant[])
GodotObject.CallDeferred(StringName, params Variant[])
GodotObject.SetDeferred(StringName, Variant)
GodotObject.Callv(StringName, Array)
GodotObject.HasMethod(StringName)
GodotObject.GetMethodArgumentCount(StringName)
GodotObject.HasSignal(StringName)
GodotObject.GetSignalList()
GodotObject.GetSignalConnectionList(StringName)
GodotObject.GetIncomingConnections()
GodotObject.Disconnect(StringName, Callable)
GodotObject.IsConnected(StringName, Callable)
GodotObject.HasConnections(StringName)
GodotObject.IsBlockingSignals()
GodotObject.NotifyPropertyListChanged()
GodotObject.CanTranslateMessages()
GodotObject.Tr(StringName, StringName)
GodotObject.GetTranslationDomain()
GodotObject.SetTranslationDomain(StringName)
GodotObject.IsQueuedForDeletion()
GodotObject.CancelFree()
GodotObject.EmitSignalScriptChanged()
GodotObject.EmitSignalPropertyListChanged()
GodotObject.NativeInstance
GodotObject.ScriptChanged
GodotObject.PropertyListChanged

Properties

CellSize

Grid cell size in pixels. Used to convert between world position and grid coordinates.

[Export(PropertyHint.None, "")]
public float CellSize { get; set; }

Property Value

float

Context

The placement context providing access to the IPlacementInputBridge.

[Export(PropertyHint.None, "")]
public PlacementContext? Context { get; set; }

Property Value

PlacementContext

GridOffset

World-space offset of the grid origin. Set this so that tile (0,0) aligns with the desired world position. Exposed as an [Export] property so it can be configured from the inspector.

[Export(PropertyHint.None, "")]
public Vector2 GridOffset { get; set; }

Property Value

Vector2

GridPosition

The current grid position of the cursor.

public Vector2I GridPosition { get; }

Property Value

Vector2I

InputBridge

The cached input bridge. Updated on _Ready().

protected IPlacementInputBridge? InputBridge { get; }

Property Value

IPlacementInputBridge

InputSettings

Input configuration for all cursor actions. Create as a CursorInputSettings resource or set in code.

[Export(PropertyHint.None, "")]
public CursorInputSettings? InputSettings { get; set; }

Property Value

CursorInputSettings

IsDragging

Whether a drag gesture is currently in progress (ConfirmAction held).

public bool IsDragging { get; }

Property Value

bool

SnapToGrid

When true, GridPosition snaps to the nearest tile centre. When false, the raw tile coordinate under the cursor is used.

[Export(PropertyHint.None, "")]
public bool SnapToGrid { get; set; }

Property Value

bool

Methods

EmitSignalCancelPressed()

protected void EmitSignalCancelPressed()

EmitSignalConfirmPressed()

protected void EmitSignalConfirmPressed()

EmitSignalGridPositionChanged(Vector2I)

protected void EmitSignalGridPositionChanged(Vector2I gridPosition)

Parameters

gridPosition Vector2I

IsHeadless()

Returns whether the cursor is currently in headless mode. In headless mode all input processing is suspended.

public bool IsHeadless()

Returns

bool

SetDragActive(bool)

Programmatically activates or deactivates drag mode.

public void SetDragActive(bool active)

Parameters

active bool

Whether drag mode should be active.

SetGridOffset(Vector2)

Sets the grid origin offset for coordinate conversion.

public void SetGridOffset(Vector2 offset)

Parameters

offset Vector2

The world-space offset to apply before snapping.

SetGridSize(float)

Sets the grid size for coordinate conversion.

public void SetGridSize(float size)

Parameters

size float

The cell size in pixels.

SetHeadlessMode(bool)

Switches between headless (server-side) and engine (visual) mode. In headless mode all input processing is suspended.

public void SetHeadlessMode(bool headless)

Parameters

headless bool

Whether to enable headless mode.

WorldToGrid(Vector2)

Converts a world-space position to a grid tile coordinate.

public Vector2I WorldToGrid(Vector2 worldPosition)

Parameters

worldPosition Vector2

World-space position.

Returns

Vector2I

The corresponding grid tile as Godot.Vector2I.

_ExitTree()

Called when the node is about to leave the Godot.SceneTree (e.g. upon freeing, scene changing, or after calling Godot.Node.RemoveChild(Godot.Node) in a script). If the node has children, its Godot.Node._ExitTree() callback will be called last, after all its children have left the tree.

Corresponds to the Godot.Node.NotificationExitTree notification in _Notification(int) and signal Godot.Node.TreeExiting. To get notified when the node has already left the active tree, connect to the Godot.Node.TreeExited.

public override void _ExitTree()

_Process(double)

Called during the processing step of the main loop. Processing happens at every frame and as fast as possible, so the delta time since the previous frame is not constant. delta is in seconds.

It is only called if processing is enabled, which is done automatically if this method is overridden, and can be toggled with SetProcess(bool).

Processing happens in order of Godot.Node.ProcessPriority, lower priority values are called first. Nodes with the same priority are processed in tree order, or top to bottom as seen in the editor (also known as pre-order traversal).

Corresponds to the Godot.Node.NotificationProcess notification in _Notification(int).

Note: This method is only called if the node is present in the scene tree (i.e. if it's not an orphan).

Note: delta will be larger than expected if running at a framerate lower than Godot.Engine.PhysicsTicksPerSecond / Godot.Engine.MaxPhysicsStepsPerFrame FPS. This is done to avoid "spiral of death" scenarios where performance would plummet due to an ever-increasing number of physics steps per frame. This behavior affects both _Process(double) and _PhysicsProcess(double). As a result, avoid using delta for time measurements in real-world seconds. Use the Godot.Time singleton's methods for this purpose instead, such as Godot.Time.GetTicksUsec().

public override void _Process(double delta)

Parameters

delta double

_Ready()

Called when the node is "ready", i.e. when both the node and its children have entered the scene tree. If the node has children, their Godot.Node._Ready() callbacks get triggered first, and the parent node will receive the ready notification afterwards.

Corresponds to the Godot.Node.NotificationReady notification in _Notification(int). See also the @onready annotation for variables.

Usually used for initialization. For even earlier initialization, Godot.GodotObject.GodotObject() may be used. See also Godot.Node._EnterTree().

Note: This method may be called only once for each node. After removing a node from the scene tree and adding it again, Godot.Node._Ready() will not be called a second time. This can be bypassed by requesting another call with Godot.Node.RequestReady(), which may be called anywhere before adding the node again.

public override void _Ready()

Events

CancelPressed

Emitted when the cancel input action is pressed (Escape / configured action). Connect to PlacementInputController which routes it to the bridge.

public event Cursor2D.CancelPressedEventHandler CancelPressed

Event Type

Cursor2D.CancelPressedEventHandler

ConfirmPressed

Emitted when the confirm input action is pressed (Enter / numpad Enter / configured action). Connect to PlacementInputController which routes it to the bridge.

public event Cursor2D.ConfirmPressedEventHandler ConfirmPressed

Event Type

Cursor2D.ConfirmPressedEventHandler

GridPositionChanged

Emitted whenever the grid position changes to a different tile.

public event Cursor2D.GridPositionChangedEventHandler GridPositionChanged

Event Type

Cursor2D.GridPositionChangedEventHandler