Player.gd 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. extends CharacterBody3D
  2. const SPEED = 5.0
  3. const JUMP_VELOCITY = 4.5
  4. # Get the gravity from the project settings to be synced with RigidBody nodes.
  5. var gravity = ProjectSettings.get_setting("physics/3d/default_gravity")
  6. var movement = true
  7. @onready var neck := $Neck
  8. @onready var camera := $Neck/Camera3D
  9. @onready var gun_cam := $Neck/Camera3D
  10. @onready var pause_screen := $"Neck/Camera3D/Pause Screen"
  11. @onready var raycast = $Neck/Camera3D/RayCast3D
  12. @onready var hand = $Neck/Hand
  13. @onready var mobile_controls = camera.get_node("mobile controls")
  14. @export_group("headbob")
  15. @export var headbob_frequency := 2.0
  16. @export var headbob_amplitude := 0.04
  17. var headbob_time := 0.0
  18. @onready var footstep_audio = $footstep
  19. var footstep_can_play := true
  20. var footstep_landed
  21. func fire():
  22. if hand.get_child_count() > 0 and hand.get_child(0).is_in_group("gun"):
  23. hand.get_child(0).fire(raycast, self)
  24. func die(message = "you die"):
  25. $"Neck/Camera3D/interaction".visible = false
  26. $"Neck/Camera3D/objectives".visible = false
  27. $Neck/Camera3D/inventory.visible = false
  28. $Neck/Camera3D/hitmarker.visible = false
  29. $"Neck/Camera3D/mobile controls".visible = false
  30. $"Neck/Camera3D/Death Screen".visible = true
  31. $"Neck/Camera3D/Death Screen/title".text = message
  32. GameManager.remove_objectives()
  33. GameManager.objectives_visible(false)
  34. Input.mouse_mode = Input.MOUSE_MODE_VISIBLE
  35. get_tree().paused = true
  36. func _unhandled_input(event):
  37. if event is InputEventMouseButton and not GameManager.is_running_on_mobile():
  38. Input.mouse_mode = Input.MOUSE_MODE_CAPTURED
  39. elif event.is_action_pressed("pause"):
  40. pause_screen.pause()
  41. if Input.mouse_mode == Input.MOUSE_MODE_CAPTURED and not GameManager.is_running_on_mobile() and movement:
  42. if event is InputEventMouseMotion:
  43. neck.rotate_y(-event.relative.x * 0.01)
  44. camera.rotate_x(-event.relative.y * 0.01)
  45. elif GameManager.is_running_on_mobile() and movement:
  46. if event is InputEventScreenDrag:
  47. neck.rotate_y(-event.relative.x * 0.01)
  48. camera.rotate_x(-event.relative.y * 0.01)
  49. func _process(_delta):
  50. camera.rotation.x = clamp(camera.rotation.x, deg_to_rad(-60), deg_to_rad(60))
  51. func _physics_process(delta):
  52. if not movement: return
  53. if not is_on_floor():
  54. velocity.y -= gravity * delta
  55. # Handle jump.
  56. if Input.is_action_just_pressed("jump") and is_on_floor():
  57. velocity.y = JUMP_VELOCITY
  58. var input_dir = Input.get_vector("left", "right", "forwards", "backwards")
  59. var direction = (neck.transform.basis * Vector3(input_dir.x, 0, input_dir.y)).normalized()
  60. if direction:
  61. velocity.x = direction.x * SPEED
  62. velocity.z = direction.z * SPEED
  63. else:
  64. velocity.x = move_toward(velocity.x, 0, SPEED)
  65. velocity.z = move_toward(velocity.z, 0, SPEED)
  66. move_and_slide()
  67. gun_cam.global_transform = camera.global_transform
  68. fire()
  69. headbob_time += delta * velocity.length() * float(is_on_floor())
  70. camera.transform.origin = headbob(headbob_time)
  71. $Neck/Hand.rotation = $Neck/Camera3D.rotation
  72. if not footstep_landed and is_on_floor():
  73. footstep_audio.play()
  74. elif footstep_landed and not is_on_floor():
  75. footstep_audio.play()
  76. footstep_landed = is_on_floor()
  77. func headbob(time):
  78. var headbob_position = Vector3.ZERO
  79. headbob_position.y = sin(time * headbob_frequency) * headbob_amplitude
  80. headbob_position.x = cos(time * headbob_frequency / 2) * headbob_amplitude
  81. var footstep_thershold = -headbob_amplitude + 0.002
  82. if headbob_position.y > footstep_thershold:
  83. footstep_can_play = true
  84. elif headbob_position.y < footstep_thershold and footstep_can_play:
  85. footstep_can_play = false
  86. footstep_audio.play()
  87. return headbob_position
  88. func _ready():
  89. if GameManager.is_running_on_mobile():
  90. mobile_controls.visible = true