Up to date

This page is up to date for Godot 4.2. If you still find outdated information, please open an issue.

Transformación de Viewport y Canvas

Introducción

Esto es un resumen de lo que sucede con las matrices de transformación 2D en los nodos desde el momento en que dibujan su contenido localmente hasta el momento en que se muestran en pantalla. Aquí se mostrarán detalles de muy bajo nivel de el motor.

The goal of this tutorial is to teach a way for feeding input events to the Input with a position in the correct coordinate system.

A more extensive description of all coordinate systems and 2d transforms is available in 2D coordinate systems and 2D transforms.

Transformación del canvas

Como se mencionó en el tutorial anterior, Capas de Canvas, cada nodo CanvasItem (recuerda que los nodos basados en Node2D y Control usan CanvasItem como su raíz común) residirá en una Canvas Layer. Cada canvas layer tiene una transformación (translation, rotation, scale, etc.) a la que se puede acceder mediante Transform2D.

Esto también está cubierto por el tutorial anterior, los nodos son dibujados por defecto en Layer (capa) 0, en el "built-in canvas" (el canvas por defecto del viewport). Para colocar nodos en una capa distinta, se debe utilizar una CanvasLayer.

Transformación global del canvas

Viewports also have a Global Canvas transform (also a Transform2D). This is the master transform and affects all individual Canvas Layer transforms. Generally, this is primarily used in Godot's CanvasItem Editor.

Transformación de estiramiento

Por último, los Viewports tienen un Stretch Transform, que se utiliza al cambiar de tamaño o estirar la pantalla. Esta transformación se utiliza internamente (como se describe en Múltiples resoluciones) pero también se puede configurar manualmente en cada Viewport.

Input events are multiplied by this transform but lack the ones above. To convert InputEvent coordinates to local CanvasItem coordinates, the CanvasItem.make_input_local() function was added for convenience.

Window transform

The root viewport is a Window. In order to scale and position the Window's content as described in Múltiples resoluciones, each Window contains a window transform. It is for example responsible for the black bars at the Window's sides so that the Viewport is displayed with a fixed aspect ratio.

Orden de Transform

To convert a CanvasItem local coordinate to an actual screen coordinate, the following chain of transforms must be applied:

../../_images/viewport_transforms3.webp

Funciones de Transform

The above graphic shows some available transform functions. All transforms are directed from right to left, this means multiplying a transform with a coordinate results in a coordinate system further to the left, multiplying the affine inverse of a transform results in a coordinate system further to the right:

# Called from a CanvasItem.
canvas_pos = get_global_transform() * local_pos
local_pos = get_global_transform().affine_inverse() * canvas_pos

Finalmente, para convertir un CanvasItem de coordenadas locales a coordenadas de pantalla, utilizar el siguiente orden:

var screen_coord = get_viewport().get_screen_transform() * get_global_transform_with_canvas() * local_pos

Tener en cuenta que esto no es aconsejable para trabajar en coordenadas de pantalla. Lo recomendable es simplemente trabajar en coordenadas de Canvas (CanvasItem.get_global_transform()), para permitir que el cambio de tamaño/ajuste de resolución funcione de la manera adecuada.

Generando eventos de entrada personalizados

It is often desired to feed custom input events to the game. With the above knowledge, to correctly do this in the focused window, it must be done the following way:

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)