How can I optimise large amounts of objects?

Godot Version

4.4

Question

Hi, I have a simple polygon model with an animation and I’m spawning in about 500 of them, this runs poorly on a well specced PC (Ryzen 7 7800x3d, 4070).

The script on this model is a simple state machine that just calculates some random movement via:

func PhysicsUpdate(_delta: float):
	var forward_motion: Vector3 = move_direction * fish_context.move_speed
	fish_context.fish.velocity = forward_motion
	fish_context.fish.move_and_slide()
	animation_player.play(swim_animation_name)

	for i in fish_context.fish.get_slide_collision_count():
		var collision: KinematicCollision3D = fish_context.fish.get_slide_collision(i)
		if collision:
			move_direction = -move_direction
			is_bouncing = true
			bounce_time = 0.01
			break

What are some techniques I can do to optimise this object and make it way more performant? Should I reduce the poly count even more, limit the animation? Are there any programming techniques to run these objects efficiently?

Thanks.

It depends.

I assume this is what you’ve identified as being the bottleneck. There are some things like using a Multimesh node to draw multiple objects (docs), not making the same call to the animation_player each physics frame but some other things that could be suspects are interaction with the SceneTree; e.g. do the the fish need to be nodes? Using the physics server directly (link) could handle collisions… a further question could be do they even need physics? One could use boids (link) to handle movement and avoidance, and further optimisation could then be spatial partitioning (e.g. no avoidance if nobody is near/in a fishes ‘sector’). Movement could be handled by a background thread, updating the main thread when appropriate but then it really depends on what’s slowing things down and how much performance you want.

The extreme end of the spectrum could then be using a compute shader to do all the work.

2 Likes