How to apply a force to all objects of a certain category ?

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

Hello, beginner godot’er here.

I’m making a game about gravity. So far I have a scene with 2 rigidbodies, a planet and the player. On the player I have a script based on tutorials I found that goes like this :

func _process(delta):    
    direction_playerplanet = (planet.position - position).normalized()
    distance_playerplanet = planet.global_position.distance_to(global_position)
    f = G * ((mass_planet * mass_player) / (distance_playerplanet * distance_playerplanet))
        
func _integrate_forces(state):
    set_applied_force(thrust.rotated(rotation))
    set_applied_torque(rotation_dir * spin_thrust)
    state.add_central_force(f * direction_playerplanet)

So this works but clearly its only between those two rigidbodies. I would like to be able to have the player attracted to multiple objects as well as having objects attracted to each other. How do I do that ?

Thanks

One thing that came into my mind is that you could just loop through all those objects (player, planets, suns e.g.) in every object’s code (or maybe attach the same script to them?) and calculate the force that way. You could use groups for this: add_to_group("something") and for body in get_tree().get_nodes_in_group("something"): ... if I didn’t mess it up
( SceneTree — Godot Engine (stable) documentation in English )
but there may be better approaches

1234ab | 2021-04-04 18:58

:bust_in_silhouette: Reply From: Lopy

You could use Area2Ds for that. They have a gravity_point property to attract RigidBody2Ds inside the Area towards the specified point. Also, you can set space_override to have the various gravitational pulls combine.

Simply add the Areas to your Node2Ds and they will move along. To avoid the RigidBodies being attracted by their own Areas, you can use add_collision_exception_with().

If performance starts being an issue, try scaling your Areas based on the gravitational pull. Far away objects would be pulled so little that it is not worth checking collisions that far.