Up to date
This page is up to date for Godot 4.2
.
If you still find outdated information, please open an issue.
Viewport- und Canvas-Transformationen¶
Einführung¶
Dies ist eine Übersicht über die 2D-Transformationen, die für Nodes vom Zeitpunkt des lokalen Zeichnens ihres Inhalts bis zum Zeitpunkt des Zeichnens auf dem Bildschirm ausgeführt werden. In dieser Übersicht werden grundlegende Details des Engine erläutert.
Das Ziel dieses Tutorials ist es, eine Methode zu vermitteln, wie man Eingabeereignisse mit einer Position im richtigen Koordinatensystem an den Input weiterleitet.
Eine ausführlichere Beschreibung aller Koordinatensysteme und 2D-Transformationen finden Sie in 2D-Koordinatensysteme und 2D-Transformationen.
Canvas-Transformation¶
Wie in der vorherigen Anleitung Canvas-Ebenen erwähnt, befindet sich jeder CanvasItem-Node in einer Canvas-Ebene (denken Sie daran, dass Node2D- und Control-basierte Nodes CanvasItem als gemeinsamen Root verwenden). Jede Canvas-Ebene verfügt über eine Transformation (Verschiebung, Drehung, Skalierung usw.), auf die wie folgt zugegriffen werden kann Transform2D.
Ebenfalls im vorherigen Kapitel behandelt, werden Nodes standardmäßig in Ebene 0 im Built-in-Canvas gezeichnet. Um Nodes in einer anderen Ebene zu platzieren, kann ein CanvasLayer-Node verwendet werden.
Globale Canvas-Transformation¶
Viewports haben auch eine globale Canvas-Transformation (auch eine Transform2D). Dies ist die Master-Transformation und beeinflusst alle individuellen Canvas Layer Transformationen. Im Allgemeinen wird dies hauptsächlich im CanvasItem-Editor von Godot verwendet.
Stretch-Transformation¶
Schließlich verfügen Ansichtsfenster über eine Stretch-Transformation, die beim Ändern der Größe oder Strecken des Bildschirms verwendet wird. Diese Transformation wird intern verwendet (wie in Mehrere Auflösungen beschrieben), kann aber auch manuell für jeden Viewport festgelegt werden.
Eingabeereignisse werden mit dieser Transformation multipliziert, aber nicht mit den oben genannten. Um InputEvent-Koordinaten in lokale CanvasItem-Koordinaten umzuwandeln, wurde der Einfachheit halber die Funktion CanvasItem.make_input_local() hinzugefügt.
Window-Transformation¶
Der Root-Viewport ist ein Window. Um den Inhalt des Windows wie in Mehrere Auflösungen beschrieben zu skalieren und zu positionieren, enthält jedes Window eine Window-Transformation. Sie ist z.B. für die schwarzen Balken an den Seiten des Windows verantwortlich, damit der Viewport mit einem festen Seitenverhältnis dargestellt wird.
Transformationsreihenfolge¶
Um eine lokale CanvasItem-Koordinate in eine tatsächliche Bildschirmkoordinate umzuwandeln, muss die folgende Kette von Transformationen angewendet werden:
Transformationsfunktionen¶
Die obige Grafik zeigt einige verfügbare Transformationsfunktionen. Alle Transformationen sind von rechts nach links gerichtet, d.h. die Multiplikation einer Transformation mit einer Koordinate ergibt ein weiter links liegendes Koordinatensystem, die Multiplikation der affinen Inversen einer Transformation ergibt ein weiter rechts liegendes Koordinatensystem:
# Called from a CanvasItem.
canvas_pos = get_global_transform() * local_pos
local_pos = get_global_transform().affine_inverse() * canvas_pos
// Called from a CanvasItem.
canvasPos = GetGlobalTransform() * localPos;
localPos = GetGlobalTransform().AffineInverse() * canvasPos;
Um die lokalen CanvasItem-Koordinaten in Bildschirmkoordinaten umzuwandeln, multiplizieren Sie sie einfach in der folgenden Reihenfolge:
var screen_coord = get_viewport().get_screen_transform() * get_global_transform_with_canvas() * local_pos
var screenCord = GetViewport().GetScreenTransform() * GetGlobalTransformWithCanvas() * localPos;
Beachten Sie jedoch, dass es im Allgemeinen nicht erwünscht ist, mit Bildschirmkoordinaten zu arbeiten. Der empfohlene Ansatz besteht darin, einfach in Canvas-Koordinaten (CanvasItem.get_global_transform()
) zu arbeiten, damit die automatische Größenänderung der Bildschirmauflösung ordnungsgemäß funktioniert.
Benutzerdefinierte Eingabeereignisse weiterleiten¶
Oft ist es erwünscht, benutzerdefinierte Eingabeereignisse an das Spiel weiterzuleiten. Mit dem obigen Wissen muss dies im fokussierten Fenster auf die folgende Weise geschehen:
var local_pos = Vector2(10, 20) # Local to Control/Node2D.
var ie = InputEventMouseButton.new()
ie.button_index = MOUSE_BUTTON_LEFT
ie.position = get_viewport().get_screen_transform() * get_global_transform_with_canvas() * local_pos
Input.parse_input_event(ie)
var localPos = new Vector2(10,20); // Local to Control/Node2D.
var ie = new InputEventMouseButton()
{
ButtonIndex = MouseButton.Left,
Position = GetViewport().GetScreenTransform() * GetGlobalTransformWithCanvas() * localPos,
};
Input.ParseInputEvent(ie);