How do i generate a Polygon2D from within a script?

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By EtheraelEspeon

I’m trying to make a polygon2d from within a script, and trying to randomize its coordinates and shape. So far i’ve generated random vectors and put them into the Polygon array, but can’t figure out how to make the shape actually appear.

Ohhh!
This is the code i was using

extends Polygon2D

var display_width = ProjectSettings.get_setting(“display/window/size/width”)
var display_height = ProjectSettings.get_setting(“display/window/size/height”)
var center = Vector2(rand_range(0, display_width), rand_range(0, display_height))
var vector_num = int(floor(rand_range(5, 10)))
var max_size = 25
var vectors: PoolVector2Array

func _ready():

for i in range(0, vector_num):
	
	vectors.append(Vector2(rand_range(center.x - max_size, center.x + max_size), rand_range(center.y - max_size, center.y + max_size)))
	

polygon += vectors

I thought that “returns a copy of the PoolVector2Array rather than a reference.” meant if I went var polys = polygon, that would be a separate array and wouldn’t change the original polygon array lol.

EtheraelEspeon | 2020-07-02 21:16

Just as an unrelated tip, the append() call you posted is very busy. I try not to include any more than 5 “things” on one line of code. I learned this from Reymond Hettinger’s talks about Python. In my experience, people neglect the ability to create variables and functions out of cumbersome code. You’re the one who has to maintain it though, so it’s your call what’s cumbersome and what is acceptable.

DDoop | 2020-07-02 22:07

1 Like
:bust_in_silhouette: Reply From: DDoop

I ran some tests and this created a polygon on my end:

func _ready():
    var poly = Polygon2D.new()
    poly.set_polygon(PoolVector2Array([Vector2(40, 40),
								  Vector2(40, 50),
								  Vector2(50, 50),
								  Vector2(50, 40)
								]))
    add_child(poly)

My guess is you tried just .append()ing to the polygon PoolVector2Array, which was my first guess. Turns out it says in the docs accessing the Polygon2D.polygon property “returns a copy of the PoolVector2Array rather than a reference.” citation

:bust_in_silhouette: Reply From: Paul Mauviel

So I did some testing and it’s definitely a case where the order of the vertices is wrong causing the polygons to be ‘backwards’ (invisible).

I’ve created a scene where there’s an Area2D with a CollisionPolygon2D (which for our purposes behaves the same way as your Polygon2D)

I’ve attached a modified version of your script to it. It generates new vertices every 2 seconds and sets them to the CollisionPolygon2D.

You can run the scene with Debug-> Visible Collision Shapes to see what is happening. Some times, the polygons will generate correctly. Other times all you’ll see is a red outline of where the vertices are; this indicates a bad polygon. Here’s the script. I’ve zipped up the sample scene and sent it to you over discord

extends CollisionPolygon2D

const displaywidth = 1920
const displayheight = 1080
var center = Vector2(rand_range(0, displaywidth), rand_range(0, displayheight))
var max_size = 1
var vectors: Array = []
var how_long = 0.0

func _ready():
   
    pass

func _process(delta):
    how_long += delta
    
    if how_long > 2.0:
        max_size = 100
        vectors = []
        
        for i in range(0, 5):
            vectors.append(Vector2(rand_range(center.x - max_size, center.x + max_size), rand_range(center.y - max_size, center.y + max_size)))
            
        vectors.sort_custom(self, "sort_clockwise")
        
        set_polygon(PoolVector2Array(vectors))
        how_long = 0
    pass

func sort_clockwise(a, b):
    return a.angle() < b.angle()