reckfellENGINE

2D coordinates: local, world and viewport

Place a child at the intended point despite parent rotation and camera movement.

On this page

Choose a coordinate space

ValueMeaning
PositionPosition relative to the parent CanvasItem with ordinary transform inheritance
GlobalPositionPosition in the current canvas; not screen pixels
ToGlobal(point)Convert a point from this entity's local coordinates to canvas coordinates
ToLocal(point)The inverse conversion for this entity
GetGlobalTransformWithCanvas()Local-to-Viewport transform, including canvas and camera

For an ordinary child Entity2D, multiply the parent transform by the local transform. Adding positions does not account for rotation, scale or skew. Positive X points right and positive Y points down. Rotation uses radians; RotationDegrees uses degrees.

Place a child under the pointer

In the complete example below, Marker is a child of Rig. The handler obtains a canvas-space mouse position through Rig.GetGlobalMousePosition(), converts it to Rig's local space and assigns Marker.Position. Assigning Marker.GlobalPosition directly is another option for the same canvas.

Do not use Marker.ToLocal(target) to calculate Marker.Position: that produces coordinates relative to the marker rather than its parent. Do not assign InputEventMouseButton.Position directly to GlobalPosition: the event position is in Viewport space, which the camera can transform.

Run the example

Use a C# project with Reckfell.NET.Sdk 1.0.0 and net10.0. Save both files from the drawing guide, build and attach CanvasExample.cs to the Entity2D root of a .rscene level. Run it. The white marker starts at canvas point (88,48); the blue HUD marker starts at (24,24). A left click outside UI that consumes input moves the white marker.

CanvasExample.cs
C#
using Reckfell;

public partial class CanvasExample : Entity2D
{
    public Entity2D Rig { get; private set; } = null!;
    public LocalMarker Marker { get; private set; } = null!;
    public Camera2D Camera { get; private set; } = null!;
    public CanvasLayer Hud { get; private set; } = null!;
    public LocalMarker HudMarker { get; private set; } = null!;

    public override void _Ready()
    {
        Rig = new Entity2D { Position = new Vector2(64, 48) };
        AddChild(Rig);
        Marker = new LocalMarker { Position = new Vector2(24, 0) };
        Rig.AddChild(Marker);
        Camera = new Camera2D { Position = new Vector2(160, 120) };
        AddChild(Camera);
        Camera.MakeCurrent();
        Hud = new CanvasLayer { Layer = 1, FollowViewportEnabled = false };
        AddChild(Hud);
        HudMarker = new LocalMarker { Position = new Vector2(24, 24) };
        HudMarker.SetStyle(8, new Color(0.25f, 0.45f, 1));
        Hud.AddChild(HudMarker);
        var label = new Label { Position = new Vector2(42, 12), Text = "HUD" };
        Hud.AddChild(label);
    }

    public override void _UnhandledInput(InputEvent input)
    {
        if (input is InputEventMouseButton { Pressed: true, ButtonIndex: MouseButton.Left })
            Marker.Position = Rig.ToLocal(Rig.GetGlobalMousePosition());
    }
}

Check the calculation without a camera

Rig.Position=(64,48) and Marker.Position=(24,0) produce Marker.GlobalPosition=(88,48) with unit scale and zero rotation. Rig.Scale=(2,3) and Rig.Rotation=Pi/2 instead produce (64,96). ToLocal(ToGlobal(point)) returns the original point within float tolerance when the transform is invertible.

Zero scale makes the inverse degenerate. Hide objects with Visible instead. TopLevel=true stops parent CanvasItem transform inheritance; it does not produce screen coordinates or replace CanvasLayer for a HUD. Explicitly assign the intended transform when switching modes.

Diagnose misplaced objects

  • Error depends on parent rotation: local and global coordinates were mixed.
  • Error depends on the camera: Viewport coordinates were assigned as world coordinates.
  • HUD and world disagree: they use different canvases. Convert through the appropriate CanvasItem.
  • Position does not solve UI layout: Control anchors and containers require UI layout rules, beyond Entity2D transforms.

HUD layers

Reckfell Engine documentationBack to top ↑
QUICK LINKSGetting startedEntity hierarchyC# & .NET 10Scenes and prefabs
Reckfell guides and full API K
reckfellENGINE
RECKFELL ACCOUNT

Sign in

Sign in to your Reckfell account.

One account for the entire Reckfell platform.