Dynamically resizing a CollisionShape2D based on nodes?

Godot Version

4.3.stable.mono

Question

I’m making a drag-and-drop system. The drop targets are currently an Area2D, with a CollisionShape2D as a child node with a RectangleShape2D. But the content of the “drop targets” are dynamic at runtime, so I don’t know the size of the CollisionShape2D. Since it isn’t sized, it doesn’t detect the mouse enter and mouse exit based on the visuals.

The nodes I’m adding are themselves a Sprite with a CollisionShape2D. I was hoping this would make the drop target’s shape automatically resize based on it’s children. I’m also learning I’m hopelessly HTML/DOM brained, so what I think will happen often isn’t what happens.

So I guess my question is two…

  1. Am I doing this completely wrong, and there’s some other way to have an “automatically grows to fit contents” node that will report mouse enter and moue exit?
  2. OR how can I (on tree enter for the nodes) recalculate the size of the CollisionShape2D based on the extremities of its children?

So I changed my way of thinking. Rather than “Here’s a node that’s a target for drop, and put other nodes inside it”, I instead made my DropTarget scene…

  • an Area2D and CollisionShape (rectangle), and an @export var of “Other node I want to be droppable”
  • connected to that node’s child enter/exit to detect when the UI size has changed
  • will recursively go through that node and create a merged rect based on the children.
  • change it’s own CollisionShape to be the correct position, then modify the shape’s Size to be the correct size

One tip to anyone doing something similar… even though I’d seen it in action in the editor, it didn’t click until after many banging-head sessions why the RectangleShape2D wasn’t covering the proper area.

If I have a node at 100,50, and it is 10x10-- I position the CollisionShape at 100,50 and make the Rectangle size 10x10-- the resulting rectangle is centered on the CollisionShape’s position. So you end up with a rectangle covering (95,45) to (105,55).
I was assuming the rectangle was drawn starting at the CollisionShape’s position, and would go from (100,50) to (110, 60). Oops.

If you need to show an image and also detect the mouse enter/exit you can use the TextureRect node that will show an image and also have the mouse_entered/exited signal without need any other node. Otherwise you can use Sprite2D.get_rect() to get the sprite size and resize your CollisionShape2D.