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
-
GodotObjectNodeCanvasItemNode2DCursor2D
- 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.PositionNode2D.RotationNode2D.RotationDegreesNode2D.ScaleNode2D.SkewNode2D.TransformNode2D.GlobalPositionNode2D.GlobalRotationNode2D.GlobalRotationDegreesNode2D.GlobalScaleNode2D.GlobalSkewNode2D.GlobalTransformCanvasItem.NotificationTransformChangedCanvasItem.NotificationLocalTransformChangedCanvasItem.NotificationDrawCanvasItem.NotificationVisibilityChangedCanvasItem.NotificationEnterCanvasCanvasItem.NotificationExitCanvasCanvasItem.NotificationWorld2DChangedCanvasItem._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.DrawPolygon(ReadOnlySpan<Vector2>, ReadOnlySpan<Color>, ReadOnlySpan<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.VisibleCanvasItem.ModulateCanvasItem.SelfModulateCanvasItem.ShowBehindParentCanvasItem.TopLevelCanvasItem.ClipChildrenCanvasItem.LightMaskCanvasItem.VisibilityLayerCanvasItem.ZIndexCanvasItem.ZAsRelativeCanvasItem.YSortEnabledCanvasItem.TextureFilterCanvasItem.TextureRepeatCanvasItem.MaterialCanvasItem.UseParentMaterialCanvasItem.DrawCanvasItem.VisibilityChangedCanvasItem.HiddenCanvasItem.ItemRectChangedNode.NotificationEnterTreeNode.NotificationExitTreeNode.NotificationMovedInParentNode.NotificationReadyNode.NotificationPausedNode.NotificationUnpausedNode.NotificationPhysicsProcessNode.NotificationProcessNode.NotificationParentedNode.NotificationUnparentedNode.NotificationSceneInstantiatedNode.NotificationDragBeginNode.NotificationDragEndNode.NotificationPathRenamedNode.NotificationChildOrderChangedNode.NotificationInternalProcessNode.NotificationInternalPhysicsProcessNode.NotificationPostEnterTreeNode.NotificationDisabledNode.NotificationEnabledNode.NotificationResetPhysicsInterpolationNode.NotificationEditorPreSaveNode.NotificationEditorPostSaveNode.NotificationWMMouseEnterNode.NotificationWMMouseExitNode.NotificationWMWindowFocusInNode.NotificationWMWindowFocusOutNode.NotificationWMCloseRequestNode.NotificationWMGoBackRequestNode.NotificationWMSizeChangedNode.NotificationWMDpiChangeNode.NotificationVpMouseEnterNode.NotificationVpMouseExitNode.NotificationWMPositionChangedNode.NotificationOsMemoryWarningNode.NotificationTranslationChangedNode.NotificationWMAboutNode.NotificationCrashNode.NotificationOsImeUpdateNode.NotificationApplicationResumedNode.NotificationApplicationPausedNode.NotificationApplicationFocusInNode.NotificationApplicationFocusOutNode.NotificationTextServerChangedNode.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.NameNode.UniqueNameInOwnerNode.SceneFilePathNode.OwnerNode.MultiplayerNode.ProcessModeNode.ProcessPriorityNode.ProcessPhysicsPriorityNode.ProcessThreadGroupNode.ProcessThreadGroupOrderNode.ProcessThreadMessagesNode.PhysicsInterpolationModeNode.AutoTranslateModeNode.EditorDescriptionNode.ReadyNode.RenamedNode.TreeEnteredNode.TreeExitingNode.TreeExitedNode.ChildEnteredTreeNode.ChildExitingTreeNode.ChildOrderChangedNode.ReplacingByNode.EditorDescriptionChangedNode.EditorStateChangedGodotObject.NotificationPostinitializeGodotObject.NotificationPredeleteGodotObject.NotificationExtensionReloadedGodotObject.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.NativeInstanceGodotObject.ScriptChangedGodotObject.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
Context
The placement context providing access to the IPlacementInputBridge.
[Export(PropertyHint.None, "")]
public PlacementContext? Context { get; set; }
Property Value
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
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
IsDragging
Whether a drag gesture is currently in progress (ConfirmAction held).
public bool IsDragging { get; }
Property Value
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
Methods
EmitSignalCancelPressed()
protected void EmitSignalCancelPressed()
EmitSignalConfirmPressed()
protected void EmitSignalConfirmPressed()
EmitSignalGridPositionChanged(Vector2I)
protected void EmitSignalGridPositionChanged(Vector2I gridPosition)
Parameters
gridPositionVector2I
IsHeadless()
Returns whether the cursor is currently in headless mode. In headless mode all input processing is suspended.
public bool IsHeadless()
Returns
SetDragActive(bool)
Programmatically activates or deactivates drag mode.
public void SetDragActive(bool active)
Parameters
activeboolWhether drag mode should be active.
SetGridOffset(Vector2)
Sets the grid origin offset for coordinate conversion.
public void SetGridOffset(Vector2 offset)
Parameters
offsetVector2The world-space offset to apply before snapping.
SetGridSize(float)
Sets the grid size for coordinate conversion.
public void SetGridSize(float size)
Parameters
sizefloatThe 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
headlessboolWhether to enable headless mode.
WorldToGrid(Vector2)
Converts a world-space position to a grid tile coordinate.
public Vector2I WorldToGrid(Vector2 worldPosition)
Parameters
worldPositionVector2World-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
deltadouble
_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
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
GridPositionChanged
Emitted whenever the grid position changes to a different tile.
public event Cursor2D.GridPositionChangedEventHandler GridPositionChanged