summaryrefslogblamecommitdiffstats
path: root/character/fps_controller/fps_controller.gd
blob: c6c3dc727697acc645d4df99cd65be20b2198670 (plain) (tree)
1
2
3
4
5
6
7
8
9
10



                                 
                                          
 
                                


                                    
                                   
                            

                      
                              
 
              

                                                   
                      

               
                              



                      
                 

























                                                                                                            

                       






                                                                         

                   




                                                                
 
                      

                                                              

                        










                                                                                                                                                         


                                            

                                  


                                           

                                  
extends KinematicBody

onready var camera = $Camera
onready var ray = $Camera/RayCast
onready var ladder_area = $ladder_detector

export var walk_speed : int = 10
export var accel : float = 0.2
export var gravity : int = -1
export var term_velocity : int = -35
export var jump_strength : int = 20
export var inertia : int = 5

var velocity : Vector3
var is_climbing : bool = false

func _ready():
    Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
    
func _process(_delta):
    get_input()
    
func _physics_process(_delta):
    handle_movement()
    handle_jumping()
    handle_collision()
    
func get_input():
    var dir : Vector3 = Vector3.ZERO
    
    #Get base movement input
    
    if Input.is_action_pressed("forward"):
        dir += -global_transform.basis.z
        if is_climbing:
            dir += global_transform.basis.y
    if Input.is_action_pressed("backward"):
        dir += global_transform.basis.z
        if is_climbing:
            dir += -global_transform.basis.y
    if Input.is_action_pressed("left"):
        dir += -global_transform.basis.x
    if Input.is_action_pressed("right"):
        dir += global_transform.basis.x
        
    dir = dir.normalized()
    
    #Pull X and Z values from directional input. Velocity.y will be handled in physics loop unless climbing.
    
    if is_climbing:
        velocity.y = lerp(velocity.y, dir.y * walk_speed, accel)
    
    velocity.x = lerp(velocity.x, dir.x * walk_speed, accel)
    velocity.z = lerp(velocity.z, dir.z * walk_speed, accel)

func handle_movement():
    #Apply gravity
    if !is_climbing:
        velocity.y += gravity
        if velocity.y < term_velocity:
            velocity.y = term_velocity
        
    velocity = move_and_slide(velocity, Vector3.UP, true, 4, PI/4, false)

func _input(event):
    #Handle mouse movement for camera
    if event is InputEventMouseMotion:
        self.rotate_y(-event.relative.x * Settings.mouse_sens)
        camera.rotate_x(-event.relative.y * Settings.mouse_sens)
        camera.rotation.x = clamp(camera.rotation.x, -1.2, 1.2)

func handle_jumping():
    if Input.is_action_just_pressed("jump") and is_on_floor():
        velocity.y = jump_strength

func handle_collision():
    for index in get_slide_count():
        var collision = get_slide_collision(index)
        var collider = collision.collider
        if (collider.get_class() == "RigidBody"):
            var col_force_vec = -collision.normal * inertia # rotate the force along collision normal
            # collision pos
            # > RigidBody.add_force(force, pos) > The position uses the rotation of the global coordinate system, but is centered at the object's origin.
            # > KinematicCollision.position() > The point of collision, in global coordinates.
            # So to add force at collision position, substract colliders pos from collision.position
            var col_pos = collision.position - collider.transform.origin
            collider.add_force(col_force_vec, col_pos)


func _on_ladder_detector_body_entered(body):
    if body.is_in_group("ladder"):
        is_climbing = true


func _on_ladder_detector_body_exited(body):
    if body.is_in_group("ladder"):
        is_climbing = false