Godot Version
v4.3.stable.official
on Debian Linux, “Bookworm”
Question
Hi all!
I’m trying to make a selection shape for an RTS prototype, by using a panel to draw on screen for the player, and an Area2D with rectangular collision shape for the detection of units that get selected.
My problem is, as you can see in the video, that the collisionShape2D keeps getting positioned half-up, half-left from the position it should be, which is calculated with the panel’s position and dimensions.
As you can see, the size is set correctly, since the shapes are always the same, but the offset is also always half of each axis less.
I made sure that all initial positions and the transform of every child node is reset, yet I still can’t crack this.
Any thoughts on what it could be?
In case its relevant, code for the UI node that has the Panel child (cleaned up for visibility):
signal area_selection(upper_left, lower_right)
@onready var selection_box: Panel = $SelectionBox
var is_dragging: bool = false
var initial_drag_coord: Vector2 = Vector2.ZERO
var final_drag_coord: Vector2 = Vector2.ZERO
func _process(_delta: float) -> void:
if Input.is_action_just_pressed("INPUT_LEFT_CLICK"):
is_dragging = true
initial_drag_coord = get_local_mouse_position()
print("started dragging at " + str(initial_drag_coord))
if Input.is_action_just_released("INPUT_LEFT_CLICK"):
is_dragging = false
final_drag_coord = get_local_mouse_position()
print("finished dragging at " + str(final_drag_coord))
emit_selection_data()
if is_dragging:
var mouse_pos = get_local_mouse_position()
selection_box.position = Vector2(min(initial_drag_coord.x, mouse_pos.x), min(initial_drag_coord.y, mouse_pos.y))
selection_box.size = Vector2(max(initial_drag_coord.x, mouse_pos.x), max(initial_drag_coord.y, mouse_pos.y)) - selection_box.position
func emit_selection_data():
area_selection.emit(selection_box.position, selection_box.position + selection_box.size)
And the relevant code from the main Game scene:
[...]
var currently_selected: Array[Node] = []
var area_selection_ocurred: bool = false
func _ready() -> void:
[...]
$UI.area_selection.connect(_on_area_selection)
$Area2D.monitoring = true
$Area2D.body_shape_entered.connect(_print_collision)
func _on_area_selection(upper_left, lower_right) -> void:#deberia ser bool
print("Selected area: " + str(upper_left) + str(lower_right))
print("Box size is: " + str(lower_right - upper_left))
$Area2D/CollisionShape2D.position = upper_left
$Area2D/CollisionShape2D.shape.size = lower_right - upper_left
area_selection_ocurred = true
func _print_collision(_body_rid: RID, body: Node2D, _body_shape_index: int, _local_shape_index: int) -> void:
if area_selection_ocurred:
print(body)
print(body.get_parent())
if body.is_in_group("selectable"):
currently_selected.append(body)
area_selection_ocurred = false