How do you make the player jump on a planet with realistic gravity?

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

Hey everyone! Thank you for clicking on my question. This is my first post on this website, so feel free to leave some constructive criticism regarding my post, if you’d like.

I’m relatively new to Godot and I have recently started my first 3D project. I’m making a shooter, where the player is defending an objective against waves of enemies. This takes place on a planet with “realistic” gravity. I watched and read plenty of tutorials, but I could not find answers to my question.

This is the problem I ran into: I want to apply current_gravity to the player in a way that it always pulls the player toward the center of the planet, but I don’t know how to do it.

Here is a short video of my project so far: https://youtu.be/yJkafqUAZnU

extends KinematicBody

Variables.

#Physics
var speed = 20
var acceleration = 20
var earth_gravity = 9.8
var current_gravity = earth_gravity
var MAX_SLOPE_ANGLE = 40
var fall = Vector3()

#Jump
var jump_power = 200
var jump_pressed = 0

#General
var mouse_sensitivity = 0.05
var is_on_ground = false

#Nodes
onready var Head = $Head

This rotates the player or the player’s head when the mouse is moved.

func _input(event):
	if event is InputEventMouseMotion:
		rotate_y(deg2rad(-event.relative.x * mouse_sensitivity))
		Head.rotate_x(deg2rad(-event.relative.y * mouse_sensitivity))

.

func _process(delta):
	#Declares a variable that serves as the up vector
	var up = get_gravity_dir_vector()

This checks if player is standing on ground.

	if $GroundChecker.is_colliding():
		is_on_ground = true
	else:
		is_on_ground = false
	
	

This rotates the player toward the center of the planet. I copied it from one of Pigeonaut’s videos on Youtube.

	transform = transform.orthonormalized()
	if transform.basis.y.normalized().cross(get_gravity_dir_vector()) != Vector3():
		look_at(Global.world_node.get_node("Planet").global_transform.origin, transform.basis.y)
	elif transform.basis.x.normalized().cross(get_gravity_dir_vector()) != Vector3():
		look_at(Global.world_node.get_node("Planet").global_transform.origin, transform.basis.x)
	
	
	

This part should apply gravity to the player, when they are not standing on ground.

	if not is_on_ground:
#		fall.y += current_gravity * delta  <==  This works on a flat surface, but not on a sphere. I tried rotating fall, but it didn't work.
	
	

This part should make the player jump.

	if Input.is_action_pressed("jump") and is_on_ground:
#		fall.y = jump_power <== This also works on a flat surface, but not on the planet.
	
	

This handles player movement on the surface of the planet.

	var vel = Vector3()
	if Input.is_action_pressed("move_forward"):
		vel += transform.basis.y
	if Input.is_action_pressed("move_backward"):
		vel -= transform.basis.y
	if Input.is_action_pressed("move_left"):
		vel -= transform.basis.x
	if Input.is_action_pressed("move_right"):
		vel += transform.basis.x 
	
	vel	*= speed
	vel = move_and_slide(vel,get_gravity_dir_vector(),0.05,4,deg2rad(MAX_SLOPE_ANGLE), false)

This part is supposed to move the player vertically.

	move_and_slide(fall, up) 

This calculates the up direction relative to the player’s position on the planet.

func get_gravity_dir_vector():
	return(Global.world_node.get_node("Planet").transform.origin - transform.origin).normalized()
:bust_in_silhouette: Reply From: DaddyMonster

Here’s realistic gravity my friend:

func newtonian_gravity(delta, obj_1, obj_2):
	obj_1.velocity += (obj_2.global_transform.origin\
		- obj_1.global_transform.origin).normalized()\
		* GRAVITY * obj_2.mass\
		/ pow((obj_2.global_transform.origin.\
		distance_to(obj_1.global_transform.origin)), 2) * delta
	obj_1.move_and_slide(obj_1.velocity, Vector3.DOWN)

To run this, just make an array of your objects and call the method like so:

func _process(delta):
	for obj_1 in planets:
		for obj_2 in planets:
			if obj_1 != obj_2:
				newtonian_gravity(delta, obj_1, obj_2)

Give each object a mass value. Gravity is very weak so your planet will need a big mass like pow(10, 19). The const GRAVITY is 0.00000000000666726.

This will work for n body problems so you can make a solar system if you want or just a single planet.

Any issues, blame Newton. :wink:

Thank you so much for your help! :slight_smile: it’s all very clear now!

UMTomato | 2020-08-13 22:13

Glad it helped! I’ve subbed to your YT channel so if you post it in action I’ll take a look.

DaddyMonster | 2020-08-14 08:57

Thank you so much for your help and patience, it works perfectly now!

UMTomato | 2020-08-19 10:25