123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233 |
- extends CharacterBody3D
- # Walking variables.
- const norm_grav = -38.8
- const MAX_SPEED = 22
- const JUMP_SPEED = 26
- const ACCEL= 8.5
- # Sprinting variables. Similar to the varibles above, just allowing for quicker movement
- const MAX_SPRINT_SPEED = 34
- const SPRINT_ACCEL = 18
- # How fast we slow down, and the steepest angle we can climb.
- const DEACCEL= 28
- const MAX_SLOPE_ANGLE = 40
- # How fast the bullets launch
- const LEFT_MOUSE_FIRE_TIME = 0.15
- const BULLET_SPEED = 100
- var vel = Vector3()
- # A vector for storing the direction the player intends to walk towards.
- var dir = Vector3()
- # A boolean to track whether or not we are sprinting
- var is_sprinting = false
- # You may need to adjust depending on the sensitivity of your mouse
- var MOUSE_SENSITIVITY = 0.08
- # A boolean for tracking whether the jump button is down
- var jump_button_down = false
- # The current lean value (our position on the lean track) and the path follow node
- var lean_value = 0.5
- # A variable for tracking if the right mouse button is down.
- var right_mouse_down = false
- # A variable for tracking if we can fire using the left mouse button
- var left_mouse_timer = 0
- # A boolean for tracking whether we can change animations or not
- var anim_done = true
- # The current animation name
- var current_anim = "Starter"
- # The simple bullet rigidbody
- var simple_bullet = preload("res://fps/simple_bullet.tscn")
- # We need the camera for getting directional vectors. We rotate ourselves on the Y-axis using
- # the camera_holder to avoid rotating on more than one axis at a time.
- @onready var camera_holder = $CameraHolder
- @onready var camera = $CameraHolder/LeanPath/PathFollow3D/IK_LookAt_Chest/Camera3D
- @onready var path_follow_node = $CameraHolder/LeanPath/PathFollow3D
- # The animation player for aiming down the sights.
- @onready var anim_player = $CameraHolder/AnimationPlayer
- # The end of the pistol.
- @onready var pistol_end = $CameraHolder/Weapon/Pistol/PistolEnd
- func _ready():
- anim_player.animation_finished.connect(self.animation_finished)
- set_physics_process(true)
- Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
- set_process_input(true)
- func _physics_process(delta):
- process_input(delta)
- process_movement(delta)
- func process_input(delta):
- # Reset dir, so our previous movement does not effect us
- dir = Vector3()
- # Get the camera's global transform so we can use its directional vectors
- var cam_xform = camera.get_global_transform()
- # ----------------------------------
- # Walking
- if Input.is_key_pressed(KEY_UP) or Input.is_key_pressed(KEY_W):
- dir += -cam_xform.basis[2]
- if Input.is_key_pressed(KEY_DOWN) or Input.is_key_pressed(KEY_S):
- dir += cam_xform.basis[2]
- if Input.is_key_pressed(KEY_LEFT) or Input.is_key_pressed(KEY_A):
- dir += -cam_xform.basis[0]
- if Input.is_key_pressed(KEY_RIGHT) or Input.is_key_pressed(KEY_D):
- dir += cam_xform.basis[0]
- if Input.is_action_just_pressed(&"ui_cancel"):
- if Input.get_mouse_mode() == Input.MOUSE_MODE_VISIBLE:
- Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
- else:
- Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE)
- if Input.is_mouse_button_pressed(2):
- if not right_mouse_down:
- right_mouse_down = true
- if anim_done:
- if current_anim != "Aiming":
- anim_player.play("Aiming")
- current_anim = "Aiming"
- else:
- anim_player.play("Idle")
- current_anim = "Idle"
- anim_done = false
- else:
- right_mouse_down = false
- if Input.is_mouse_button_pressed(1):
- if left_mouse_timer <= 0:
- left_mouse_timer = LEFT_MOUSE_FIRE_TIME
- # Create a bullet
- var new_bullet = simple_bullet.instantiate()
- get_tree().root.add_child(new_bullet)
- new_bullet.global_transform = pistol_end.global_transform
- new_bullet.linear_velocity = new_bullet.global_transform.basis.z * BULLET_SPEED
- if left_mouse_timer > 0:
- left_mouse_timer -= delta
- # ----------------------------------
- # ----------------------------------
- # Sprinting
- if Input.is_key_pressed(KEY_SHIFT):
- is_sprinting = true
- else:
- is_sprinting = false
- # ----------------------------------
- # ----------------------------------
- # Jumping
- if Input.is_key_pressed(KEY_SPACE):
- if not jump_button_down:
- jump_button_down = true
- if is_on_floor():
- vel.y = JUMP_SPEED
- else:
- jump_button_down = false
- # ----------------------------------
- # ----------------------------------
- # Leaninng
- if Input.is_key_pressed(KEY_Q):
- lean_value += 1.2 * delta
- elif Input.is_key_pressed(KEY_E):
- lean_value -= 1.2 * delta
- else:
- if lean_value > 0.5:
- lean_value -= 1 * delta
- if lean_value < 0.5:
- lean_value = 0.5
- elif lean_value < 0.5:
- lean_value += 1 * delta
- if lean_value > 0.5:
- lean_value = 0.5
- lean_value = clamp(lean_value, 0, 1)
- path_follow_node.unit_offset = lean_value
- if lean_value < 0.5:
- var lerp_value = lean_value * 2
- path_follow_node.rotation_degrees.z = (20 * (1 - lerp_value))
- else:
- var lerp_value = (lean_value - 0.5) * 2
- path_follow_node.rotation_degrees.z = (-20 * lerp_value)
- # ----------------------------------
- func process_movement(delta):
- var grav = norm_grav
- dir.y = 0
- dir = dir.normalized()
- vel.y += delta*grav
- var hvel = vel
- hvel.y = 0
- var target = dir
- if is_sprinting:
- target *= MAX_SPRINT_SPEED
- else:
- target *= MAX_SPEED
- var accel
- if dir.dot(hvel) > 0:
- if not is_sprinting:
- accel = ACCEL
- else:
- accel = SPRINT_ACCEL
- else:
- accel = DEACCEL
- hvel = hvel.lerp(target, accel*delta)
- vel.x = hvel.x
- vel.z = hvel.z
- # TODO: This information should be set to the CharacterBody properties instead of arguments.
- velocity = vel
- move_and_slide()
- # Mouse based camera movement
- func _input(event):
- if event is InputEventMouseMotion and Input.get_mouse_mode() == Input.MOUSE_MODE_CAPTURED:
- rotate_y(deg2rad(event.relative.x * MOUSE_SENSITIVITY * -1))
- camera_holder.rotate_x(deg2rad(event.relative.y * MOUSE_SENSITIVITY))
- # We need to clamp the camera's rotation so we cannot rotate ourselves upside down
- var camera_rot = camera_holder.rotation_degrees
- if camera_rot.x < -40:
- camera_rot.x = -40
- elif camera_rot.x > 60:
- camera_rot.x = 60
- camera_holder.rotation_degrees = camera_rot
- else:
- pass
- func animation_finished(_anim):
- anim_done = true
|