How to draw shapes in correct position in godot engine?

Viewed 397

I am trying to make a selection tool. The collision shape is drawn correctly, as you can see in form of the filled box. While the mouse is dragged, I want to draw a green rectangle. However, the box is drawn in the wrong place. What am I missing? Screenshot

extends Area2D

onready var shape: Shape2D = $CollisionShape2D.shape
onready var collision: CollisionShape2D = $CollisionShape2D

export (Color, RGBA) var color = Color.green
export var stroke_width: float = 1.0
export (bool) var isFilled = true

var startOfDrag: Vector2
var endOfDrag: Vector2
var width: int = 1
var height: int = 1
var isMouseDragged: bool = false

var points: PoolVector2Array

func _process(delta: float) -> void:
if isMouseDragged:
    update()

func _draw():
draw_polyline(points , color, stroke_width, isFilled)

func _input(event: InputEvent) -> void:
if Input.is_action_just_pressed("left_mouse_down") and not isMouseDragged:
    startOfDrag = get_global_mouse_position()
    position = startOfDrag
    shape.set_extents(Vector2(1, 1))
    isMouseDragged = true

if Input.is_action_just_released("left_mouse_down"):
    isMouseDragged = false
    handleSelection()

endOfDrag = get_global_mouse_position()
    
width = abs(startOfDrag.x - endOfDrag.x)
height = abs(startOfDrag.y - endOfDrag.y)

change_rectangle()

func handleSelection() -> void:
shape.set_extents(Vector2(width/2, height/2))
collision.position = Vector2(width/2, height/2)

func change_rectangle() -> void:
points = []
points.append(Vector2(startOfDrag.x, startOfDrag.y))
points.append(Vector2(startOfDrag.x + width, startOfDrag.y))
points.append(Vector2(startOfDrag.x + width, startOfDrag.y + height))
points.append(Vector2(startOfDrag.x, startOfDrag.y + height))
points.append(Vector2(startOfDrag.x, startOfDrag.y))
1 Answers

This is what I see:

startOfDrag = get_global_mouse_position()
position = startOfDrag

The mouse position is in global coordinates. While the position of your object is in local coordinates (you can think of it as coordinates relative to the parent).

Set the global_position instead:

startOfDrag = get_global_mouse_position()
global_position = startOfDrag

By the way, the method to_local converts global coordinates to local coordinates of the node on which you call it. Similarly, there is a to_global method that will convert local coordinates of the node on which you call it to global coordinates.

Keep track of which vectors are in global coordinates and which are in local coordinates.


If there is scaling applied your width and height might also not match. If you run into that, you should be able to fix it with to_local of the CollisionShape2D.

Related