Description
It's not uncommon to create Polygon2D objects intended for collision detection with a CollisionObject2D, such as an Area2D or PhysicsBody2D, where we want the collider to be a CollisionPolygon2D that uses the same polygon shape as the Polygon2D we have drawn. This can be easily done in code using something like
my_collision_polygon.polygon = my_polygon2D.polygon
since both the Polygon2D and CollisionPolygon2D store their polygons as a PackedVector2Array of vertices.
If you want the collision shape to follow the polygon automatically, as you create the polygon in the editor, you can do that by making a script inherit from CollisionPolygon2D with the @tool
decoration (or [Tool]
attribute if using C#).
Setting a class_name
also lets you easily select this type when adding a new node in the editor. (In C# you would want to use the [GlobalClass]
attribute instead.)
The following is a bit rough just to get the point across, so you'll want to adjust to your needs. (It's safer to obtain a reference to the Polygon2D object via some other approach, such as an @export
variable, rather than calling get_parent twice. It would also be cleaner to place code having the same effect in the Polygon2D object instead, since then that object is managing its children rather than the other way around.)
You can set interval
to whatever time delay you want before the polygon updates.
Notice the line if not Engine.is_editor_hint(): return
ensures that the polygon shape is only updated while in the editor. This is important, since (for example) since it likely wastes processor cycles and changing the polygon while running the game will cause events to re-trigger, which is undesirable. (So, for example, if you are listening to the Area2D's mouse_entered and mouse_exited signals, these would go off every half-second when the polygon is reset.) If you do want additional _process
code to run in-game, then this should be adjusted accordingly. If you intend the Polygon2D object's vertices to change in-game through code, then it is probably better to just assign the polygon when that happens, rather than use continuous polling in the _process
method.
Main code
@tool
class_name AutoUpdateCollisionPolygon2D
extends CollisionPolygon2D
var interval : float = .5
var timer : float = 0.
var following : Polygon2D
func _ready():
var area = get_parent()
if area:
var grandparent = area.get_parent()
if grandparent:
following = grandparent
func _process(delta):
if not following: return
if not Engine.is_editor_hint(): return
timer += delta
if timer > interval:
timer = 0.
self.polygon = following.polygon