reckfellENGINE

Координаты 2D: локальные, мировые и экранные

Как переместить дочернюю Entity в нужную точку при повороте родителя и движении камеры.

На этой странице

Выбрать систему координат

ЗначениеЧто означает
PositionПозиция относительно родительского CanvasItem при обычном наследовании трансформации
GlobalPositionПозиция в пространстве текущего canvas; это не пиксели экрана
ToGlobal(point)Точка из локальных координат этой Entity в пространство canvas
ToLocal(point)Обратное преобразование для этой Entity
GetGlobalTransformWithCanvas()Трансформация из локальных координат в координаты Viewport, включая canvas и камеру

Для обычного дочернего Entity2D мировая трансформация получается умножением трансформации родителя на локальную. Нельзя заменять это сложением Position: поворот, масштаб и skew меняют результат. Начало 2D направлено вправо по X и вниз по Y; Rotation задаётся в радианах, RotationDegrees — в градусах.

Поставить дочерний объект под курсор

В полном примере ниже Marker — ребёнок Rig. Обработчик получает позицию мыши в пространстве canvas через Rig.GetGlobalMousePosition(), затем переводит её в локальные координаты Rig. Результат присваивается Marker.Position. Альтернатива для этого же canvas — присвоить Marker.GlobalPosition напрямую.

Не используйте Marker.ToLocal(target) для вычисления Marker.Position: тогда вы получите координаты относительно самой метки, а не её родителя. Не передавайте InputEventMouseButton.Position прямо в GlobalPosition: координаты события принадлежат Viewport, и камера может их преобразовывать.

Запустить пример

Нужен C#-проект Reckfell.NET.Sdk 1.0.0, net10.0. Сохраните два файла из руководства по рисованию, соберите проект и прикрепите CanvasExample.cs к корню Entity2D уровня .rscene. Запустите уровень; белая метка появляется в canvas-точке (88, 48), синяя — в точке HUD (24, 24). Щелчок левой кнопкой вне перехватывающего ввод интерфейса переносит белую метку.

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());
    }
}

Проверить расчёт без камеры

У Rig.Position=(64,48), Marker.Position=(24,0). При единичном масштабе и нулевом повороте Marker.GlobalPosition=(88,48). Если Rig.Scale=(2,3), Rig.Rotation=Pi/2, результат — (64,96). ToLocal(ToGlobal(point)) возвращает исходную точку с погрешностью float, если трансформация обратима.

Нулевой масштаб делает обратное преобразование вырожденным. Не используйте его как способ скрыть объект; меняйте Visible. TopLevel=true отключает наследование трансформации родительского CanvasItem, но не превращает координаты в экранные и не заменяет CanvasLayer для HUD. При переключении режима явно задавайте нужную трансформацию.

Если объект попадает не туда

  • Ошибка зависит от поворота родителя: смешаны локальные и мировые координаты.
  • Ошибка зависит от камеры: координаты Viewport присвоены как мировые.
  • HUD и мир дают разные точки: они находятся в разных canvas. Преобразовывайте через соответствующий CanvasItem, а не через случайную Entity.
  • Изменение Position не решает проблему интерфейса: Control с anchors и контейнерами требует правил UI, а не только Entity2D.

Слои HUD

Документация Reckfell EngineНаверх ↑
БЫСТРЫЙ ПЕРЕХОДНачало работыEntity и иерархияC# & .NET 10Сцены и префабы
Руководства и полный API Reckfell K
reckfellENGINE
RECKFELL ACCOUNT

Вход в аккаунт

Войдите в аккаунт Reckfell.

Один аккаунт для всей платформы Reckfell.