extends Spatial class_name SolarSystem const G = 6.674 * pow(10, -11) # Because we're dealing with a miniature, we want small masses and distances to have noticeable # gravitational effects. These multipliers adapt the scale of the game to an earth-like scale. const mass_multiplier = pow(10, 24) # thus, the earth would get a mass of 6 const distance_multiplier = 318550 # thus, a radius of 20 results in an earth-like radius # If the gravity doesn't feel like it should, this scales it. A higher value means that the pull is # stronger. const gravity_multiplier = 10.0 # Return the gravity acceleration vector to the closest planet, not taking all other planets into # account. # This is useful for keeping something firmly on the planet while it is touching it, or for creating # a predictable orbit. func get_closest_gravity_acceleration(position: Vector3) -> Vector3: var closest_planet_distance = INF var closest_force = 0.0 # Iterate through all planets to find the closest one for planet in get_children(): var pos_to_center = (planet.transform.origin - position) var distance = pos_to_center.length() if distance < closest_planet_distance: # This planet is closer than the previous ones -> calculate and save the values var force = _gravity(planet.mass * mass_multiplier, distance * distance_multiplier) force *= gravity_multiplier # Multiply by the normalized vector towards the center to give the force a direction closest_force = (pos_to_center / distance) * force closest_planet_distance = distance return closest_force # Return the total gravity acceleration vector experienced at that position. func get_gravity_acceleration(position: Vector3) -> Vector3: var total_force = Vector3.ZERO # Add each planet's gravity force to the total force for planet in get_children(): var pos_to_center = (planet.transform.origin - position) var distance = pos_to_center.length() var force = _gravity(planet.mass * mass_multiplier, distance * distance_multiplier) force *= gravity_multiplier total_force += (pos_to_center / distance) * force return total_force # Return the velocity needed to orbit the given planet func get_orbit_velocity(position: Vector3, planet): var pos_to_center = (planet.global_transform.origin - position) var distance = pos_to_center.length() # raw_velocity is the velocity according to the formula, but we also need to account for the gravity_multiplier. var raw_velocity = -sqrt((G * planet.mass * mass_multiplier) / (distance * distance_multiplier)) var gravity_scale_factor = sqrt(gravity_multiplier / distance_multiplier) return raw_velocity * gravity_scale_factor # Formula for gravity static func _gravity(mass, distance): return (G * mass) / (distance * distance)