example_player.gd 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  1. extends CharacterBody3D
  2. # Walking variables.
  3. const norm_grav = -38.8
  4. const MAX_SPEED = 22
  5. const JUMP_SPEED = 26
  6. const ACCEL= 8.5
  7. # Sprinting variables. Similar to the varibles above, just allowing for quicker movement
  8. const MAX_SPRINT_SPEED = 34
  9. const SPRINT_ACCEL = 18
  10. # How fast we slow down, and the steepest angle we can climb.
  11. const DEACCEL= 28
  12. const MAX_SLOPE_ANGLE = 40
  13. # How fast the bullets launch
  14. const LEFT_MOUSE_FIRE_TIME = 0.15
  15. const BULLET_SPEED = 100
  16. var vel = Vector3()
  17. # A vector for storing the direction the player intends to walk towards.
  18. var dir = Vector3()
  19. # A boolean to track whether or not we are sprinting
  20. var is_sprinting = false
  21. # You may need to adjust depending on the sensitivity of your mouse
  22. var MOUSE_SENSITIVITY = 0.08
  23. # A boolean for tracking whether the jump button is down
  24. var jump_button_down = false
  25. # The current lean value (our position on the lean track) and the path follow node
  26. var lean_value = 0.5
  27. # A variable for tracking if the right mouse button is down.
  28. var right_mouse_down = false
  29. # A variable for tracking if we can fire using the left mouse button
  30. var left_mouse_timer = 0
  31. # A boolean for tracking whether we can change animations or not
  32. var anim_done = true
  33. # The current animation name
  34. var current_anim = "Starter"
  35. # The simple bullet rigidbody
  36. var simple_bullet = preload("res://fps/simple_bullet.tscn")
  37. # We need the camera for getting directional vectors. We rotate ourselves on the Y-axis using
  38. # the camera_holder to avoid rotating on more than one axis at a time.
  39. @onready var camera_holder = $CameraHolder
  40. @onready var camera = $CameraHolder/LeanPath/PathFollow3D/IK_LookAt_Chest/Camera3D
  41. @onready var path_follow_node = $CameraHolder/LeanPath/PathFollow3D
  42. # The animation player for aiming down the sights.
  43. @onready var anim_player = $CameraHolder/AnimationPlayer
  44. # The end of the pistol.
  45. @onready var pistol_end = $CameraHolder/Weapon/Pistol/PistolEnd
  46. func _ready():
  47. anim_player.animation_finished.connect(self.animation_finished)
  48. set_physics_process(true)
  49. Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
  50. set_process_input(true)
  51. func _physics_process(delta):
  52. process_input(delta)
  53. process_movement(delta)
  54. func process_input(delta):
  55. # Reset dir, so our previous movement does not effect us
  56. dir = Vector3()
  57. # Get the camera's global transform so we can use its directional vectors
  58. var cam_xform = camera.get_global_transform()
  59. # ----------------------------------
  60. # Walking
  61. if Input.is_key_pressed(KEY_UP) or Input.is_key_pressed(KEY_W):
  62. dir += -cam_xform.basis[2]
  63. if Input.is_key_pressed(KEY_DOWN) or Input.is_key_pressed(KEY_S):
  64. dir += cam_xform.basis[2]
  65. if Input.is_key_pressed(KEY_LEFT) or Input.is_key_pressed(KEY_A):
  66. dir += -cam_xform.basis[0]
  67. if Input.is_key_pressed(KEY_RIGHT) or Input.is_key_pressed(KEY_D):
  68. dir += cam_xform.basis[0]
  69. if Input.is_action_just_pressed(&"ui_cancel"):
  70. if Input.get_mouse_mode() == Input.MOUSE_MODE_VISIBLE:
  71. Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
  72. else:
  73. Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE)
  74. if Input.is_mouse_button_pressed(2):
  75. if not right_mouse_down:
  76. right_mouse_down = true
  77. if anim_done:
  78. if current_anim != "Aiming":
  79. anim_player.play("Aiming")
  80. current_anim = "Aiming"
  81. else:
  82. anim_player.play("Idle")
  83. current_anim = "Idle"
  84. anim_done = false
  85. else:
  86. right_mouse_down = false
  87. if Input.is_mouse_button_pressed(1):
  88. if left_mouse_timer <= 0:
  89. left_mouse_timer = LEFT_MOUSE_FIRE_TIME
  90. # Create a bullet
  91. var new_bullet = simple_bullet.instantiate()
  92. get_tree().root.add_child(new_bullet)
  93. new_bullet.global_transform = pistol_end.global_transform
  94. new_bullet.linear_velocity = new_bullet.global_transform.basis.z * BULLET_SPEED
  95. if left_mouse_timer > 0:
  96. left_mouse_timer -= delta
  97. # ----------------------------------
  98. # ----------------------------------
  99. # Sprinting
  100. if Input.is_key_pressed(KEY_SHIFT):
  101. is_sprinting = true
  102. else:
  103. is_sprinting = false
  104. # ----------------------------------
  105. # ----------------------------------
  106. # Jumping
  107. if Input.is_key_pressed(KEY_SPACE):
  108. if not jump_button_down:
  109. jump_button_down = true
  110. if is_on_floor():
  111. vel.y = JUMP_SPEED
  112. else:
  113. jump_button_down = false
  114. # ----------------------------------
  115. # ----------------------------------
  116. # Leaninng
  117. if Input.is_key_pressed(KEY_Q):
  118. lean_value += 1.2 * delta
  119. elif Input.is_key_pressed(KEY_E):
  120. lean_value -= 1.2 * delta
  121. else:
  122. if lean_value > 0.5:
  123. lean_value -= 1 * delta
  124. if lean_value < 0.5:
  125. lean_value = 0.5
  126. elif lean_value < 0.5:
  127. lean_value += 1 * delta
  128. if lean_value > 0.5:
  129. lean_value = 0.5
  130. lean_value = clamp(lean_value, 0, 1)
  131. path_follow_node.unit_offset = lean_value
  132. if lean_value < 0.5:
  133. var lerp_value = lean_value * 2
  134. path_follow_node.rotation_degrees.z = (20 * (1 - lerp_value))
  135. else:
  136. var lerp_value = (lean_value - 0.5) * 2
  137. path_follow_node.rotation_degrees.z = (-20 * lerp_value)
  138. # ----------------------------------
  139. func process_movement(delta):
  140. var grav = norm_grav
  141. dir.y = 0
  142. dir = dir.normalized()
  143. vel.y += delta*grav
  144. var hvel = vel
  145. hvel.y = 0
  146. var target = dir
  147. if is_sprinting:
  148. target *= MAX_SPRINT_SPEED
  149. else:
  150. target *= MAX_SPEED
  151. var accel
  152. if dir.dot(hvel) > 0:
  153. if not is_sprinting:
  154. accel = ACCEL
  155. else:
  156. accel = SPRINT_ACCEL
  157. else:
  158. accel = DEACCEL
  159. hvel = hvel.lerp(target, accel*delta)
  160. vel.x = hvel.x
  161. vel.z = hvel.z
  162. # TODO: This information should be set to the CharacterBody properties instead of arguments.
  163. velocity = vel
  164. move_and_slide()
  165. # Mouse based camera movement
  166. func _input(event):
  167. if event is InputEventMouseMotion and Input.get_mouse_mode() == Input.MOUSE_MODE_CAPTURED:
  168. rotate_y(deg2rad(event.relative.x * MOUSE_SENSITIVITY * -1))
  169. camera_holder.rotate_x(deg2rad(event.relative.y * MOUSE_SENSITIVITY))
  170. # We need to clamp the camera's rotation so we cannot rotate ourselves upside down
  171. var camera_rot = camera_holder.rotation_degrees
  172. if camera_rot.x < -40:
  173. camera_rot.x = -40
  174. elif camera_rot.x > 60:
  175. camera_rot.x = 60
  176. camera_holder.rotation_degrees = camera_rot
  177. else:
  178. pass
  179. func animation_finished(_anim):
  180. anim_done = true