Can't append values onto a PoolVector2Array...?

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

I have a convex collision polygon, I am trying to add points to it in code like this:

$floor/collision_floor.shape.points.append(Vector2(1200,500))
$floor/collision_floor.shape.points.append(Vector2(0,500))
$floor/collision_floor.shape.points.append(Vector2(0,800))
$floor/collision_floor.shape.points.append(Vector2(1200,800))

print($floor/collision_floor.shape.points)

but the print output is just an empty array? What am I missing?

:bust_in_silhouette: Reply From: eddex

An array is static in size. You can’t append new values. Instead, what you want to do is create a new array with your points and then assign the new array to $floor/collision_floor.shape.points.

Example:

var array = PoolVector2Array( [ Vector2(1,2), Vector2(3,4) ] )
$floor/collision_floor.shape.points = array

I’ll give this a go, but then what does the append() function do on a PoolVector2Array exactly? It’s there on the docs, and it’s not throwing an unknown function error or anything.

psear | 2020-09-12 16:35

You’re right, those methods exist in the docs and they can actually be used. My answer was not quite correct, sorry.

So here’s a quick example:

func _ready():

# I created a polygon with an initial size of 3
print($StaticBody/CollisionPolygon.polygon.size()) # size = 3

# When we try to append a new Vector2 directly on the node, nothing happens
$StaticBody/CollisionPolygon.polygon.append(Vector2(3,3))
print($StaticBody/CollisionPolygon.polygon.size()) # size = 3

# resize doesn't work either
$StaticBody/CollisionPolygon.polygon.resize(4)
$StaticBody/CollisionPolygon.polygon.append(Vector2(5,5))
print($StaticBody/CollisionPolygon.polygon.size()) # size is 3

# however, if we create a copy of the polygon array
var array = $StaticBody/CollisionPolygon.polygon
# and append a new Vector2 
array.append(Vector2(9,9))
# and then assign it to the node
$StaticBody/CollisionPolygon.polygon = array

# the size changes as expected
print($StaticBody/CollisionPolygon.polygon.size()) # size = 4

So in conclusion: You can use the append method, but not directly on the ColisionPolygon.polygon property. You have to create a copy first and then update the ColisionPolygon.polygonproperty.

eddex | 2020-09-12 16:57

PoolVector2Array is a funny one. It’s noted in the docs that Note that this type is passed by value and not by reference.. Probably related to this class’ special properties (contiguous in memory).

When you try and access CollisionPolygon.polygon you are actually triggering the get_polygon() “getter” function which is returning by value (i.e. a copy of) the array. You then append to this copy, and immediately discard it - which isn’t what you wanted.

The docs ( https://docs.godotengine.org/en/stable/classes/class_collisionpolygon.html#class-collisionpolygon-property-polygon ) confirm that eddex’s solution is the correct one

Note: The returned value is a copy of the original. Methods which mutate the size or properties of the return value will not impact the original polygon. To change properties of the polygon, assign it to a temporary variable and make changes before reassigning the polygon member.

Tim Martin | 2020-09-12 18:14