'Godot 3: How to walk on walls using Gravity and Gravity Direction?

I want to make a 3D game on Godot with the player who can walk on walls and ceiling but I've tried to make this but it didn't work :(

This is the code of my Player First Person Controller:

extends KinematicBody

export var GravityDirection = Vector3(-9.8, 0, 0)
var held_object: Object
var velocity = Vector3.ZERO
var speed = 10
var MAX_SPEED = 30
var GravityStrength = 9.8
var throw_force: float = 200

var wall_one = Vector3(-9.8, 0, 0)
var wall_two = Vector3(0, 0, -9.8)
var wall_three = Vector3(9.8, 0, 0)
var wall_four = Vector3(0, 0, 9.8)
var ground = Vector3(0, -9.8, 0)

onready var ray = $"Camera/Hand/RayCast"
onready var hold_position = $"Camera/Hand/HoldPosition"

# Camera
onready var player_camera = $"Camera"
var spin = 0.1
export var mouse_sensitivity = 5

func _ready():
    Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)

func _physics_process(delta):
    
    var Gravity = GravityStrength * GravityDirection
    var Velocity = Gravity * delta
    move_and_collide(Velocity)
    
    var run_once = 0
    while 1:
        if run_once == 0:
            if GravityDirection == wall_one:
                rotate_x(90)
            run_once = 1
    
    player_camera.rotation_degrees.y = 180
    player_camera.rotation_degrees.z = 0
    if Input.is_action_just_pressed("player_fire"):
        fire()
        
    if not is_on_floor():
        Velocity.y += -GravityStrength
    movement(delta)
    velocity = move_and_slide(velocity, Vector3.ZERO)
    
    if Input.is_action_just_pressed("player_pick"):
        if held_object:
            held_object.mode = RigidBody.MODE_RIGID
            held_object.collision_mask = 1
            held_object = null
        else:
            if ray.get_collider():
                held_object = ray.get_collider()
                held_object.mode = RigidBody.MODE_KINEMATIC
                held_object.collision_mask = 0
    if held_object:
        held_object.global_transform.origin = hold_position.global_transform.origin
    #_process_input()
    #_process_gravity()
    

# Mouvement

func movement(_delta):
    var dir = Vector3.ZERO
    var vel_y = velocity.y
    
    velocity = Vector3.ZERO
    
    # Movement forward and backward
    if Input.is_action_pressed("player_forward"):
        dir += transform.basis.z
    elif Input.is_action_pressed("player_backward"):
        dir -= transform.basis.z
    
    # Movement Left and Right
    if Input.is_action_pressed("player_left"):
        dir += transform.basis.x
    elif Input.is_action_pressed("player_right"):
        dir -= transform.basis.x
        
    velocity = dir.normalized() * speed
    velocity.y = vel_y
    
func _input(event):
    if event is InputEventMouseMotion and Input.get_mouse_mode() == Input.MOUSE_MODE_CAPTURED:
        
        rotate_y(lerp(0, -spin, event.relative.x * (mouse_sensitivity * 0.01) ))
        player_camera.rotate_x(lerp(0,spin, event.relative.y * (mouse_sensitivity * 0.01)) )
        
        #Clamp vertical rotation
        var curr_rot = player_camera.rotation_degrees
        curr_rot.x = clamp(curr_rot.x, -60, 60)
        player_camera.rotation_degrees = curr_rot

func fire():
    print("fire")
    if ray.get_collider() != null and ray.get_collider().is_in_group("enemy"):
        print(ray.get_collider())
        ray.get_collider().hp -= 10

Nodes Configuration

In the code, you can find fonctions for the camera and gravity system. Also, there is a fonction to pick up rigid bodies. I want to make a system where when the Gravity has a specific direction, the mesh rotate to 90°. I've made a "GlobalRay" with 6 RayCast to detect collisions (walls) and register face blablabla... you've understood but I don't know how to make a system like this!!!

I think there is a way to optimize the script, so, I need help :D

If you can perform my code it's nice! Have a nice code!



Solution 1:[1]

It looks like you're subtracting GravityStrength from the player's y velocity if they are not on the floor, while you should be adding the Velocity to the player's velocity. Otherwise, this question here is very general and could be implemented in a lot of ways. wall_one, wall_two, wall_three etc. I think would be better off with a magnitude of one so they could undergo the same GravityStrength modifier as everything else in later implementations, but that's just me.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Pablo Ibarz