2D Adding shapes directly to Area2D/Body2D without Collisionshape2D

Godot Version

4.2.2+

Question

Heya guys!

The player can place a lot of objects in my game and I want to cut down on nodes since it can get laggy. I severely cut down the amount down by dynamically adding/removing collision shapes to a single Area2D.

HOWEVER that still leaves us with a Collisionshape2D for every object. If possible I’d like to cut out Collisionshape2D’s too, I tried instancing a shape and setting the shape owner to the Area2D or Collisionshape2D but couldn’t seem to get it to work.

Any help or other methods that allow for dynamic adding/removing collision shapes at runtime is appreciated!

You can use PhysicsServer2D — Godot Engine (stable) documentation in English

Something like this

var id = the_area.get_rid()
var shape_id = PhysicsServer2D.rectangle_shape_create()
PhysicsServer2D.shape_set_data(shape_id, the_shape_size)
PhysicsServer2D.area_add_shape(id, shape_id)

You can also create a shape2d object instead of creating the shape through the server api:

var shape = CircleShape2D.new()
shape.radius = 50
PhysicsServer2D.area_add_shape(the_area.get_rid(), shape.get_rid())

If I recall correctly, the shape2d object destroys its underlying shape when it’s freed so you would need to hold a reference to the shape2d obj.

1 Like

What is the average amount of nodes in these scenes?

Have you profiled this to see if it’s actually the number of nodes that’s causing the slow down?

1 Like

Thanks! I’ll give your solution a go!

It’s a sim/life game where the player can place stuff down on a pretty large property, think farm sim ish. It usually only slows down in stress testing around some overly higher numbers, but I figure if I can easily trim some fat for older machines or to allow for larger maps to decorate I will. You never know what kind of mods or crazy stuff players will do.

More than anything I kinda don’t like the idea of having 1000s of extra nodes clogging up the tree if there’s no need for them. If nothing else it’s something I’ve always been curious about and wanted to try!

I got this working perfectly thank-you! It was exactly what I was looking for~

For future humans who stumble upon this this is how I set it up!

func add_shape_to_area( _area:Area2D, _size:Vector2, _position:Vector2 ) -> float:
	var area_id = _area.get_rid()
	var shape_id = PhysicsServer2D.rectangle_shape_create()
	var shape_size = _size
	
	# Keep in mind the shape will be CENTERED here
	var shape_position = _position 
	var shape_transform = Transform2D( 0.0, shape_position ) 
	
	PhysicsServer2D.shape_set_data( shape_id, shape_size )
	PhysicsServer2D.area_add_shape( area_id, shape_id, shape_transform )
	
	return shape_id

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