Files
fmm/game/Player.gd

105 lines
3.3 KiB
GDScript

extends CharacterBody3D
const SPEED = 5.0
const JUMP_VELOCITY = 4.5
const SENSITIVITY = 0.005
const FOV_DEFAULT: float = 75.0
const FOV_SPRINT: float = 90.0
const FOV_LERP = 0.2
var gravity = ProjectSettings.get_setting("physics/3d/default_gravity")
var bullet = load("res://bullet.tscn")
@onready var head = $Head
@onready var camera = $Head/PlayerCamera
@onready var player_debug = $Head/PlayerCamera/PlayerDebug
@onready var overlay_fps = $Head/PlayerCamera/OverlayFPS
@onready var player_stats = $PlayerStats
@onready var anim_player = $AnimationPlayer
@onready var muzzle_flash = $Head/PlayerCamera/pistol/MuzzleFlash
@onready var pistol_raycast = $Head/PlayerCamera/pistol/RayCast3D
@onready var bullet_decal = preload("res://bullet_decal.tscn")
func _ready() -> void:
Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
func _unhandled_input(event: InputEvent) -> void:
if event is InputEventMouseMotion:
head.rotate_y(-event.relative.x * SENSITIVITY)
camera.rotate_x(-event.relative.y * SENSITIVITY)
camera.rotation.x = clamp(camera.rotation.x, deg_to_rad(-40), deg_to_rad(80))
if Input.is_action_just_pressed("shoot") and anim_player.current_animation != "shoot":
play_shoot_effect()
if Input.is_action_just_pressed("ui_cancel"):
if Input.mouse_mode == Input.MOUSE_MODE_VISIBLE:
get_tree().quit(0)
Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE)
if Input.is_action_just_pressed("debug_overlay"):
player_debug.visible = !player_debug.visible
if Input.is_action_just_pressed("overlay_fps"):
if !overlay_fps.visible:
overlay_fps.visible = true
elif !overlay_fps.advanced_output:
overlay_fps.advanced_output = true
else:
overlay_fps.advanced_output = false
func _physics_process(delta: float) -> void:
if not is_on_floor():
velocity.y -= gravity * delta
if Input.is_action_just_pressed("jump") and is_on_floor():
velocity.y = JUMP_VELOCITY
var input_dir = Input.get_vector("move_left", "move_right", "move_forward", "move_backward")
var direction = (head.transform.basis * Vector3(input_dir.x, 0, input_dir.y)).normalized()
if direction:
velocity.x = direction.x * player_stats.speed
velocity.z = direction.z * player_stats.speed
else:
velocity.x = 0.0
velocity.z = 0.0
if Input.is_action_pressed("sprint"):
velocity.x = velocity.x * player_stats.sprint_multiplier
velocity.z = velocity.z * player_stats.sprint_multiplier
camera.fov = lerp(camera.fov, FOV_SPRINT, FOV_LERP)
else:
camera.fov = lerp(camera.fov, FOV_DEFAULT, FOV_LERP)
# Animations
if input_dir != Vector2.ZERO and is_on_floor() and anim_player.current_animation != "shoot":
anim_player.play("move")
else:
anim_player.play("idle")
if player_debug.visible:
player_debug.add_stat("vel_x", str(velocity.x))
player_debug.add_stat("vel_y", str(velocity.y))
player_debug.add_stat("vel_z", str(velocity.z))
player_debug.add_stat("vel_tot", str(absf(velocity.z) + absf(velocity.x) + absf(velocity.y)))
player_debug.add_stat("hp", str(player_stats.current_health))
move_and_slide()
func play_shoot_effect():
anim_player.stop()
anim_player.play("shoot")
muzzle_flash.restart()
muzzle_flash.emitting = true
var parent = get_parent()
if parent:
var instance: Node3D = bullet.instantiate()
instance.position = pistol_raycast.global_position
instance.transform.basis = pistol_raycast.global_transform.basis
parent.add_child(instance)