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!



Comments

Popular posts from this blog

Spring Elasticsearch Operations

Network Error and Timeout on Authorize.net JS

Object oriented programming concepts (OOPs)