Godot Version
3.5
Question
I want to draw and animate a polygon and then detect Area2D interactions with it.
If I build my CollisionPolygon2D on _ready
everything seems to work properly. Then I wanted to animate it so I am recomputing the points in the polygon
of the CollisionPolygon2D
during _process
. When I do that, if I enable “Debug/Visible collision shapes”, I can see the Area2D properly updated but _on_Area2D_area_shape_entered
is not triggering.
I have setup a scene with a couple Area2D nodes one of which follows the mouse and reports collisions. Then I added a couple Area2D that I create on _ready
, for now using just a circle with the code below:
extends Area2D
var npoints = 32
var nradius = 160
func _ready():
var points = PoolVector2Array()
for i in range(npoints):
var coords = Vector2(cos(2.0*PI*i/npoints)*nradius, sin(2.0*PI*i/npoints)*nradius)
points.push_back(coords)
var polygon = CollisionPolygon2D.new()
polygon.build_mode =CollisionPolygon2D.BUILD_SEGMENTS
polygon.polygon = points
polygon.one_way_collision_margin = 2
call_deferred("add_child", polygon)
var line = Line2D.new()
line.width = 20
call_deferred("add_child", line)
var coords = Vector2(cos(0)*nradius, sin(0)*nradius)
points.push_back(coords)
line.points = points
line.begin_cap_mode = Line2D.LINE_CAP_BOX
This works. Then I created another one that I try to animate with the code below:
extends Area2D
var npoints = 32
var nradius = 160
var nradius_change = 30
var points = []
var polygon: CollisionPolygon2D
var circle: Line2D
func update_shapes():
var new_points = Array()
for point in points:
new_points.append(point*nradius)
polygon.polygon = PoolVector2Array(new_points)
new_points.append(new_points[0])
circle.points = PoolVector2Array(new_points)
func _ready():
for i in range(npoints):
points.append(Vector2(cos(2.0*PI*i/npoints), sin(2.0*PI*i/npoints)))
circle = Line2D.new()
polygon = CollisionPolygon2D.new()
update_shapes()
polygon.build_mode =CollisionPolygon2D.BUILD_SEGMENTS
polygon.one_way_collision_margin = 2
polygon.polygon = PoolVector2Array()
#polygon.polygon.resize(npoints)
#polygon.polygon.fill(Vector2.ZERO)
call_deferred("add_child", polygon)
circle.points = PoolVector2Array()
#circle.points.resize(npoints+1)
#circle.points.fill(Vector2.ZERO)
circle.width = 20
circle.begin_cap_mode = Line2D.LINE_CAP_BOX
call_deferred("add_child", circle)
func _process(delta):
nradius += nradius_change * delta
if nradius>250:
nradius_change *= -1
elif nradius<150:
nradius_change *= -1
update_shapes()
Reading around I tried:
- Adding
set_physics_process(true)
to_ready
- Adding
.set_physics_process(true)
to_ready
- Calling
update_shapes()
in_physics_process
What am I missing? I recorded the screen here:
p.s.
I was trying to use a single PoolVector2Array
, initialize it once (using resize
and fill
), and then just update the points in it as needed. That didn’t seem to work. I am not sure how to work with PoolVector2Array. The documentation has some notes about how it is passed by value and not mutated, does that mean I need to recreate it every time like I’m doing already?