Get gravity vector

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By František Horínek

Hi,

I am currently developing space “racing” game where the players will use local gravity fields (planets, stars, black holes) to slingshot their ships around.

I would like to draw predicted trajectory based on current position and velocity. So far I was able to implement this feature using scripts by managing the gravity by myself. The map is static and I can calculate the force pulling the player based on position.
My algorithm is:

  • get current position and velocity
  • calculate the gravity force for the position
  • calculate velocity change and get new position
  • repeat multiple times ([number of physics steps per second] * [prediciton length in seconds]), store points in array
  • draw polyline

This system works great, but I would like to use Area2D (with point gravity and gravity falloff) to do this for me since I it is already implemented and potentially much faster than scripted solution. I will still run the prediction loop from script but I would like to get the gravity vector from physics server based on global_position.

Is there a function to get gravity vector based on the global_position from the physics server?
So far I was unable to locate the method where is the gravity force is actually calculated for area2D. Can someone point me to the right direction?

Thank you

:bust_in_silhouette: Reply From: eons

The applied gravity is calculated by the server using the global gravity plus all the modifications added by the areas.

Per body, you can get the total gravity applied to them via the body state PhysicsDirectBodyState — Godot Engine (3.0) documentation in English

:bust_in_silhouette: Reply From: aftamat4ik

global gravity direction vector is this - Vector3.DOWN

but there is areas and they can change gravity direction
inside of the Rigid Body that are simulating physics you can go to
integrate_forces method
in here you can do this:

forces_state.get_total_gravity().normalized()

if you print it - result will be like this (0,-1,0) which is Down vector.
if you stay near area this vector will … point to the area

Ok, how to deal with kinematic_body in this case?
well. in Kinematic Body you by yourself should Set gravity.
So in kinematic body script add variable that represents your gravity like

 var body_gravity_vec=Vector3.DOWN

and use this variable in your calculations like so, for example:

velocity.y += body_gravity_vec *delta
velocity = move_and_slide(velocity, Vector3.UP)

now go to your Area and attach a script on it.
In Area Script there is overridable method -

body_entered ( Object body )

override it. now in this method do this

if "body_gravity_vec" in body:
    body.body_gravity_vec = self.gravity_vec

each area has it’s own self.gravity_vec based on it’s settings