Godot Version
v4.2.stable.mono.official [46dc27791]
Question
Hey all,
there is something I can’t wrap my head around for some time now.
I have a simple test project, it contains:
Node2D (Root)
- mainCamera(2D)
- cam01 (Camera2D)
- cam02 (Camera2D)
- item_Flower
- item_Key
- item_Banana
The items as well as cam01 and cam02 are own scenes.
The item scene is build like this:
Sprite2D (Root)
- Polygon2D
The polygon is created per code with this function and covers the items Sprite2D
extends Sprite2D
func _create_polygon():
var bm = BitMap.new()
bm.create_from_image_alpha(texture.get_image())
# in the original script, it was Rect2(position.x, position.y ...)
var rect = Rect2(0, 0, texture.get_width(), texture.get_height())
# change (rect, 2) for more or less precision
# for ex. (rect, 5) will have the polygon points spaced apart more
# (rect, 0.0001) will have points spaced very close together for a precise outline
var my_array = bm.opaque_to_polygons(rect, 3)
var my_polygon = Polygon2D.new()
my_polygon.set_polygons(my_array)
add_child(my_polygon)
Cam01 and cam02 are used to zoom in to the main scene screen, which works fine.
It should work like this:
Clicking somewhere triggers a check, if an item or a camera was “hit”.
Clicking into the Rect of one of the two cam0x, will activate the (zoomed) camera per make_current().
Clicking onto an item not being covered by one of cam01 or cam02 views, works with the Geometry2D.is_point_in_polygon and returns true.
The code looks like this.
if Geometry2D.is_point_in_polygon(to_local(event.position),childNode.get_polygons()[0]):
print("hit " + childNode.name + " of " + self.name)
return true
else:
print("missed " + childNode.name + " of " + self.name)
return false
If I click into the Rect of cam01 or cam02 it activates them, shows the zoomed item, but the is_point_in_polygon method does not work, because event.position or better to_local(event.position) is not delivering coordinates that will match the local 0,0 based ones of the created polygon.
to_local does calculate the coordintes relative to the item, but in the global space, not in the current zoomed camera space / view, which shows the item zoomed and therefore with a different origin and scale.
I have some Debug output that shows the issue better:
---------- event.position ----------
(434, 212) unaltered position
(876.7219, 295.1775) some position translation from sauermann from another thread here
(-1220.648, -248.6943) to_local(event.position) but it is realtive to the position of the item in the main scene camera.
(1029.086, 360.1962) to_global(event.position) also kinda relative I guess, but I could not make sense out of this
----- polygons -----
[(8, 2), (0, 13), (0, 15), (6, 24), (7, 24), (10, 40), (11, 40), (5, 83), (5, 104), (12, 128), (12, 131), (32, 161), (32, 163), (78, 201), (78, 202), (134, 227), (134, 228), (192, 237), (192, 238), (258, 235), (265, 235), (322, 215), (325, 215), (333, 207), (334, 207), (328, 190), (328, 189), (272, 171), (272, 170), (165, 148), (161, 148), (119, 128), (117, 128), (87, 101), (86, 101), (43, 50), (42, 50), (28, 5), (28, 3), (8, 0)]
missed @Polygon2D@3 of posFlag
So I can hit the polygon, if I click on the position it is in the main scene camera, but when being in the zoomed cam01 (or cam02 with another item) with the item, it doesn’t work any way I tried.
What I’m trying to achieve is some “simple” point and click with items (later on) being put into some inventory and being able to zoom into the scene per second or third camera and collecting the item in there, but for now hitting the polygon of the sprite2D would be enough.
I understand, that the polygon is based by 0,0 on the parent sprite2D and therefore relative, but not why I can’t get the event.position translate to the zoomed camera and item.
What is it I am missing here? Hope my explanation isn’t too messy, but in any case here is the project code itself:
Thanks for taking the time to read this and maybe considering an answer which helps me get this working!