player.gd 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. extends CharacterBody3D
  2. const EYE_HEIGHT_STAND = 1.6
  3. const EYE_HEIGHT_CROUCH = 1.4
  4. const MOVEMENT_SPEED_GROUND = 0.6
  5. const MOVEMENT_SPEED_AIR = 0.11
  6. const MOVEMENT_SPEED_CROUCH_MODIFIER = 0.5
  7. const MOVEMENT_FRICTION_GROUND = 0.9
  8. const MOVEMENT_FRICTION_AIR = 0.98
  9. var _mouse_motion = Vector2()
  10. var _selected_block = 6
  11. @onready var gravity = ProjectSettings.get_setting("physics/3d/default_gravity")
  12. @onready var head = $Head
  13. @onready var raycast = $Head/RayCast3D
  14. @onready var camera_attributes = $Head/Camera3D.attributes
  15. @onready var selected_block_texture = $SelectedBlock
  16. @onready var voxel_world = $"../VoxelWorld"
  17. @onready var crosshair = $"../PauseMenu/Crosshair"
  18. func _ready():
  19. Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
  20. func _process(_delta):
  21. # Mouse movement.
  22. _mouse_motion.y = clamp(_mouse_motion.y, -1560, 1560)
  23. transform.basis = Basis.from_euler(Vector3(0, _mouse_motion.x * -0.001, 0))
  24. head.transform.basis = Basis.from_euler(Vector3(_mouse_motion.y * -0.001, 0, 0))
  25. # Block selection.
  26. var ray_position = raycast.get_collision_point()
  27. var ray_normal = raycast.get_collision_normal()
  28. if Input.is_action_just_pressed(&"pick_block"):
  29. # Block picking.
  30. var block_global_position = Vector3i((ray_position - ray_normal / 2).floor())
  31. _selected_block = voxel_world.get_block_global_position(block_global_position)
  32. else:
  33. # Block prev/next keys.
  34. if Input.is_action_just_pressed(&"prev_block"):
  35. _selected_block -= 1
  36. if Input.is_action_just_pressed(&"next_block"):
  37. _selected_block += 1
  38. _selected_block = wrapi(_selected_block, 1, 30)
  39. # Set the appropriate texture.
  40. var uv = Chunk.calculate_block_uvs(_selected_block)
  41. selected_block_texture.texture.region = Rect2(uv[0] * 512, Vector2.ONE * 64)
  42. # Block breaking/placing.
  43. if crosshair.visible and raycast.is_colliding():
  44. var breaking = Input.is_action_just_pressed(&"break")
  45. var placing = Input.is_action_just_pressed(&"place")
  46. # Either both buttons were pressed or neither are, so stop.
  47. if breaking == placing:
  48. return
  49. if breaking:
  50. var block_global_position = Vector3i((ray_position - ray_normal / 2).floor())
  51. voxel_world.set_block_global_position(block_global_position, 0)
  52. elif placing:
  53. var block_global_position = Vector3i((ray_position + ray_normal / 2).floor())
  54. voxel_world.set_block_global_position(block_global_position, _selected_block)
  55. func _physics_process(delta):
  56. camera_attributes.dof_blur_far_enabled = Settings.fog_enabled
  57. camera_attributes.dof_blur_far_distance = Settings.fog_distance * 1.5
  58. camera_attributes.dof_blur_far_transition = Settings.fog_distance * 0.125
  59. # Crouching.
  60. var crouching = Input.is_action_pressed(&"crouch")
  61. head.transform.origin.y = lerpf(head.transform.origin.y, EYE_HEIGHT_CROUCH if crouching else EYE_HEIGHT_STAND, 16 * delta)
  62. # Keyboard movement.
  63. var movement_vec2 = Input.get_vector("move_left", "move_right", "move_forward", "move_back")
  64. var movement = transform.basis * (Vector3(movement_vec2.x, 0, movement_vec2.y))
  65. if is_on_floor():
  66. movement *= MOVEMENT_SPEED_GROUND
  67. else:
  68. movement *= MOVEMENT_SPEED_AIR
  69. if crouching:
  70. movement *= MOVEMENT_SPEED_CROUCH_MODIFIER
  71. # Gravity.
  72. velocity.y -= gravity * delta
  73. velocity += Vector3(movement.x, 0, movement.z)
  74. # Apply horizontal friction.
  75. velocity.x *= MOVEMENT_FRICTION_GROUND if is_on_floor() else MOVEMENT_FRICTION_AIR
  76. velocity.z *= MOVEMENT_FRICTION_GROUND if is_on_floor() else MOVEMENT_FRICTION_AIR
  77. move_and_slide()
  78. # Jumping, applied next frame.
  79. if is_on_floor() and Input.is_action_pressed(&"jump"):
  80. velocity.y = 7.5
  81. func _input(event):
  82. if event is InputEventMouseMotion:
  83. if Input.get_mouse_mode() == Input.MOUSE_MODE_CAPTURED:
  84. _mouse_motion += event.relative
  85. func chunk_pos():
  86. return Vector3i((transform.origin / Chunk.CHUNK_SIZE).floor())