CollisionShape2D Odd Behavior

Godot Version

4.2.2

Question

I was having an odd issue with some basic collision shapes, and I wanted to get other opinions since I must be missing something basic. I am fairly new to Godot, so hopefully it’s something simple.

I’ve got an object, which when a player gets within a radius, it tethers to them, and then that player gets their own radius and can tether to other players, or a “final object”. Essentially it acts like connect the dots. I wanted to make a rectangular CollisionShape2D for each connection, which set the position, rotation, and size so that it would be straight line from one vertex to the next. The position being set between two vertices, and rotation between vertices is being set correctly, but for some reason, if I have 3 or more vertices, the size of the CollisionShape2D for all of these, is being set equal to the distance between the final and penultimate vertices. Here is a picture below, with the CollisionShape2Ds in green.

Test 1

Test 2

The order goes from the statue looking object, to the player on the left, the player on the bottom, and back to the statue. As you can see, the size of all CollisionShape2Ds is being set to the size of the final one in the chain. The only code I have that is affecting this is:

if is_end_tether:
		beam_collision.global_position = 0.5 * (self.global_position + tethered_objects[tethered_objects.size() - 2].global_position)
		beam_collision.rotation = (self.global_position.angle_to_point(tethered_objects[tethered_objects.size() - 2].global_position))
		beam_collision.shape.size = Vector2(self.global_position.distance_to(tethered_objects[tethered_objects.size() - 2].global_position), 2)
	else:
		beam_collision.global_position = 0.5 * (self.global_position + previous_object.global_position)
		beam_collision.rotation = (self.global_position.angle_to_point(previous_object.global_position))
		beam_collision.shape.size = Vector2(self.global_position.distance_to(previous_object.global_position), 2)

The “is_end_tether” is just a bool and checks if a vertex has already been connected to, making it an end so it won’t make any more chains, or if it is a designated “final object” and won’t make any more chains.

It’s also confusing since this same code is practically reused from the code that sets the position, rotation, and size of the texture of the beam, and it works fine, although the size portion is dealing with the region rect of the Sprite2D and not the Shape of a CollisionShape2D.

As a side note, is there any reason to use “shape.set_size()” over “shape.size = Vector2(x, y)”? Or any difference between “shape.size” and “shape.extents”?

Im assuming that the problem is that they share their collisionshape. That means when you change one collision-shape, all of them will change since they reference the same point in memory.
The easy solution to avoid this is to click on the Shape2D-property in the collisionshape and click on “Resource” and set “local_to_scene” to true

Explanation:
The Shape2D is a resource, resources have the advantage that they can be shared between several nodes/scripts if they need the same data, saving on memory. But if you change it in one node, it will also change for all the other nodes, since they use the same shape

That did the trick. I didn’t know that they would be shared between nodes to save memory, good to know for the future.

I see that the texture part of the beam worked before, and it doesn’t have an option to change to local_to_scene, so only certain properties or things can be shared between nodes? If theres a resource that explains more on that I’d love to see it, if anyone knows of a resource.

Thanks for the help!

I know a “resource” :wink:

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.