+1 vote

Hi!

I am trying to make a project that implements physics that resembles Super Mario Galaxy, where someone can walk around a planet perpendicular to where they are standing and, and they can jump to other planets. As research, I read this article and this video, but I have no idea how to actually implement the system. Below is an image of a sample level that I want to make. I eventually want to add non-sphere planets. The code I have for the ray (called "Gravity Calculator") and the Player are shown below. I don't know if I have to use `look_at()` or something, but I honestly have no idea. Any help is appreciated :)

Level:

Raycast (Gravity Calculator) Code:

``````extends RayCast

#   pass # Replace with function body.

func _process(delta):
ray_to_planet()

func nearest_planet():
#Get all planets and assume the first one is the closest
var planets = get_node("../../Planets").get_children()
var nearest_planet = planets[0]

# Compare the distance from the assumed nearest to the other planet(s)
for planet in planets:
if planet.get_translation().distance_to(player.get_translation()) > nearest_planet.get_translation().distance_to(player.get_translation()):
nearest_planet = planet
# Return the nearest planet
return nearest_planet

func ray_to_planet():
#Get the relative distance from the player to the nearest planet and set the ray to cast there
var raydestination = nearest_planet().get_translation() - player.get_translation()
set_cast_to(raydestination)
return get_cast_to()

func ray_normal():
return get_collision_normal()
``````

Player Code:

``````extends KinematicBody

onready var ray = get_node("Gravity Calculator")

var velocity = Vector3(0,0,0)

var gravity = 3

pass # Replace with function body.

func _process(delta):
_move_by_input(delta)
move_and_slide(velocity, ray.get_collision_normal(), true)

func _physics_process(delta):
velocity.y = velocity.y - gravity * delta
_move_by_input(delta)
velocity = move_and_slide(velocity, Vector3.UP, true)

func _move_by_input(delta):
if Input.is_action_pressed("move_forwards"):
velocity.z -= 1
if Input.is_action_pressed("move_backwards"):
velocity.z += 1
if Input.is_action_pressed("move_right"):
velocity.x += 1
if Input.is_action_pressed("move_left"):
velocity.x -= 1
``````
in Engine

Try looking on github. I downloaded a couple of demos when researching the same ideas, I know one of them used raycast to get the normals of the objects. I'll check if I can find them.

https://github.com/LeonardMeagher2/godot-gravity-aligned-character
I saw this one, but haven't tried it.

https://github.com/BlenderSleuth/GravityPrototypes
I downloaded this one, I think it's FPS, haven't opened in a long time.

https://github.com/BlenderSleuth/godot_gravity_tests
Downloaded and checked, moves a character model around a planet, has jump and collision.

Hope they help you figure out how it works, I've checked the codes, but it was a while ago.

Hey! Thanks for the links. The third one seemed to be the closest to what I was trying to do. When I added the code, it got the "walking around the planet" mechanic working, but whenever the player tried to switch planets, it stopped working, even after editing the code to make the ray point towards the nearest planet. You can see the code in action here. Do you have any ideas?

I put together a small demo scene based on the third link I suggested to you.

https://github.com/DamonRaziel/GravityMultiPlanetDemo

You change planets by jumping on the pads and pressing "c".

To stop the player getting stuck on a planet, I disable the player rays and colliders. To point to a new planet, I set planet_position to the Vector3 of the target planet.

I added a cube planet to test extra shapes.

Transitions between planets and sides of the cube are not smooth and polished, but the essentials are there.

Hope it helps.

by (114 points)
selected by