+1 vote

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?

in Engine by (252 points)

1 Answer

+2 votes

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
by (109 points)

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.

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.

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.
Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read How to use this Q&A? before posting your first questions.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to webmaster@godotengine.org with your username.