Bugbot/Scenes/bugbot_player.gd

273 lines
12 KiB
GDScript

class_name Bugbot
extends CharacterBody3D
@export_group("Inputs")
@export_subgroup("Keyboard")
@export var keyboard_move_forward : InputEventKey
@export var keyboard_move_backward : InputEventKey
@export var keyboard_move_left : InputEventKey
@export var keyboard_move_right : InputEventKey
@export var keyboard_move_up : InputEventKey
@export var keyboard_move_down : InputEventKey
@export var keyboard_tilt_up : InputEventKey
@export var keyboard_tilt_down : InputEventKey
@export var keyboard_pan_left : InputEventKey
@export var keyboard_pan_right : InputEventKey
@export var keyboard_movement_speed_up : InputEventKey
@export var keyboard_movement_speed_down : InputEventKey
@export var keyboard_place_marker : InputEventKey
@export var keyboard_exit_placement : InputEventKey
@export_subgroup("Mouse")
@export var mouse_movement_speed_up : InputEventMouseButton
@export var mouse_movement_speed_down : InputEventMouseButton
@export var mouse_place_marker : InputEventMouseButton
@export var mouse_exit_placement : InputEventMouseButton
@export_subgroup("Joystick")
@export var joypad_move_forward : InputEventJoypadMotion
@export var joypad_move_backward : InputEventJoypadMotion
@export var joypad_move_left : InputEventJoypadMotion
@export var joypad_move_right : InputEventJoypadMotion
@export var joypad_move_up : InputEventJoypadMotion
@export var joypad_move_down : InputEventJoypadMotion
@export var joypad_tilt_up : InputEventJoypadMotion
@export var joypad_tilt_down : InputEventJoypadMotion
@export var joypad_pan_left : InputEventJoypadMotion
@export var joypad_pan_right : InputEventJoypadMotion
@export var joypad_movement_speed_up : InputEventJoypadButton
@export var joypad_movement_speed_down : InputEventJoypadButton
@export var joypad_place_marker : InputEventJoypadButton
@export var joypad_exit_placement : InputEventJoypadButton
@onready var laser_beam : Node3D = $LaserBeamRoot as Node3D
@onready var movement_speed_change_timer : Timer = $MovementSpeedChangeTimer as Timer
@onready var exit_placement_timer : Timer = $ExitPlacementTimer as Timer
@onready var camera : Camera3D = $CollisionShape3D/Camera3D
var movement_speed : float = 5.0
var stored_camera : Camera3D
var stored_mouse_mode : int = Input.MOUSE_MODE_CAPTURED
var stored_pause_status : bool = false
var raycast_collision : Dictionary
static func instantiate(tree:SceneTree) -> void:
tree.root.add_child(load("res://addons/Bugbot/Scenes/bugbot_player.tscn").instantiate() as CharacterBody3D)
#region Initialisation
func _enter_tree() -> void:
stored_camera = get_viewport().get_camera_3d()
stored_pause_status = get_tree().paused
get_tree().paused = true
stored_mouse_mode = Input.mouse_mode
Input.mouse_mode = Input.MOUSE_MODE_CAPTURED
#region Movement Configuration
InputMap.add_action(&"bugbot_move_forward", 0.1)
InputMap.action_add_event(&"bugbot_move_forward", keyboard_move_forward)
InputMap.action_add_event(&"bugbot_move_forward", joypad_move_forward)
InputMap.add_action(&"bugbot_move_backward", 0.1)
InputMap.action_add_event(&"bugbot_move_backward", keyboard_move_backward)
InputMap.action_add_event(&"bugbot_move_backward", joypad_move_backward)
InputMap.add_action(&"bugbot_move_left", 0.1)
InputMap.action_add_event(&"bugbot_move_left", keyboard_move_left)
InputMap.action_add_event(&"bugbot_move_left", joypad_move_left)
InputMap.add_action(&"bugbot_move_right", 0.1)
InputMap.action_add_event(&"bugbot_move_right", keyboard_move_right)
InputMap.action_add_event(&"bugbot_move_right", joypad_move_right)
InputMap.add_action(&"bugbot_move_down", 0.1)
InputMap.action_add_event(&"bugbot_move_down", keyboard_move_down)
InputMap.action_add_event(&"bugbot_move_down", joypad_move_down)
InputMap.add_action(&"bugbot_move_up", 0.1)
InputMap.action_add_event(&"bugbot_move_up", keyboard_move_up)
InputMap.action_add_event(&"bugbot_move_up", joypad_move_up)
#endregion
#region Camera Configuration
InputMap.add_action(&"bugbot_tilt_up", 0.1)
InputMap.action_add_event(&"bugbot_tilt_up", keyboard_tilt_up)
InputMap.action_add_event(&"bugbot_tilt_up", joypad_tilt_up)
InputMap.add_action(&"bugbot_tilt_down", 0.1)
InputMap.action_add_event(&"bugbot_tilt_down", keyboard_tilt_down)
InputMap.action_add_event(&"bugbot_tilt_down", joypad_tilt_down)
InputMap.add_action(&"bugbot_pan_left", 0.1)
InputMap.action_add_event(&"bugbot_pan_left", keyboard_pan_left)
InputMap.action_add_event(&"bugbot_pan_left", joypad_pan_left)
InputMap.add_action(&"bugbot_pan_right", 0.1)
InputMap.action_add_event(&"bugbot_pan_right", keyboard_pan_right)
InputMap.action_add_event(&"bugbot_pan_right", joypad_pan_right)
#endregion
#region Speed Configuration
InputMap.add_action(&"bugbot_movement_speed_up")
InputMap.action_add_event(&"bugbot_movement_speed_up", keyboard_movement_speed_up)
InputMap.action_add_event(&"bugbot_movement_speed_up", mouse_movement_speed_up)
InputMap.action_add_event(&"bugbot_movement_speed_up", joypad_movement_speed_up)
InputMap.add_action(&"bugbot_movement_speed_down")
InputMap.action_add_event(&"bugbot_movement_speed_down", keyboard_movement_speed_down)
InputMap.action_add_event(&"bugbot_movement_speed_down", mouse_movement_speed_down)
InputMap.action_add_event(&"bugbot_movement_speed_down", joypad_movement_speed_down)
#endregion
#region Marker Placement Configuration
InputMap.add_action(&"bugbot_place_marker")
InputMap.action_add_event(&"bugbot_place_marker", keyboard_place_marker)
InputMap.action_add_event(&"bugbot_place_marker", mouse_place_marker)
InputMap.action_add_event(&"bugbot_place_marker", joypad_place_marker)
InputMap.add_action(&"bugbot_exit_placement")
InputMap.action_add_event(&"bugbot_exit_placement", keyboard_exit_placement)
InputMap.action_add_event(&"bugbot_exit_placement", mouse_exit_placement)
InputMap.action_add_event(&"bugbot_exit_placement", joypad_exit_placement)
#endregion
func _exit_tree() -> void:
#region Movement Deconfiguration
InputMap.action_erase_event(&"bugbot_move_forward", keyboard_move_forward)
InputMap.action_erase_event(&"bugbot_move_forward", joypad_move_forward)
InputMap.action_erase_event(&"bugbot_move_backward", keyboard_move_backward)
InputMap.action_erase_event(&"bugbot_move_backward", joypad_move_backward)
InputMap.action_erase_event(&"bugbot_move_left", keyboard_move_left)
InputMap.action_erase_event(&"bugbot_move_left", joypad_move_left)
InputMap.action_erase_event(&"bugbot_move_right", keyboard_move_right)
InputMap.action_erase_event(&"bugbot_move_right", joypad_move_right)
InputMap.action_erase_event(&"bugbot_move_down", keyboard_move_down)
InputMap.action_erase_event(&"bugbot_move_down", joypad_move_down)
InputMap.action_erase_event(&"bugbot_move_up", keyboard_move_up)
InputMap.action_erase_event(&"bugbot_move_up", joypad_move_up)
#endregion
#region Camera Deconfiguration
InputMap.action_erase_event(&"bugbot_tilt_up", keyboard_tilt_up)
InputMap.action_erase_event(&"bugbot_tilt_up", joypad_tilt_up)
InputMap.action_erase_event(&"bugbot_tilt_down", keyboard_tilt_down)
InputMap.action_erase_event(&"bugbot_tilt_down", joypad_tilt_down)
InputMap.action_erase_event(&"bugbot_pan_left", keyboard_pan_left)
InputMap.action_erase_event(&"bugbot_pan_left", joypad_pan_left)
InputMap.action_erase_event(&"bugbot_pan_right", keyboard_pan_right)
InputMap.action_erase_event(&"bugbot_pan_right", joypad_pan_right)
#endregion
#region Speed Deconfiguration
InputMap.action_erase_event(&"bugbot_movement_speed_up", keyboard_movement_speed_up)
InputMap.action_erase_event(&"bugbot_movement_speed_up", mouse_movement_speed_up)
InputMap.action_erase_event(&"bugbot_movement_speed_up", joypad_movement_speed_up)
InputMap.action_erase_event(&"bugbot_movement_speed_down", keyboard_movement_speed_down)
InputMap.action_erase_event(&"bugbot_movement_speed_down", mouse_movement_speed_down)
InputMap.action_erase_event(&"bugbot_movement_speed_down", joypad_movement_speed_down)
#endregion
#region Marker Placement Deconfiguration
InputMap.action_erase_event(&"bugbot_place_marker", keyboard_place_marker)
InputMap.action_erase_event(&"bugbot_place_marker", mouse_place_marker)
InputMap.action_erase_event(&"bugbot_place_marker", joypad_place_marker)
InputMap.action_erase_event(&"bugbot_exit_placement", keyboard_exit_placement)
InputMap.action_erase_event(&"bugbot_exit_placement", mouse_exit_placement)
InputMap.action_erase_event(&"bugbot_exit_placement", joypad_exit_placement)
#endregion
#region Action Removal
InputMap.erase_action(&"bugbot_move_forward")
InputMap.erase_action(&"bugbot_move_backward")
InputMap.erase_action(&"bugbot_move_left")
InputMap.erase_action(&"bugbot_move_right")
InputMap.erase_action(&"bugbot_move_down")
InputMap.erase_action(&"bugbot_move_up")
InputMap.erase_action(&"bugbot_tilt_up")
InputMap.erase_action(&"bugbot_tilt_down")
InputMap.erase_action(&"bugbot_pan_left")
InputMap.erase_action(&"bugbot_pan_right")
InputMap.erase_action(&"bugbot_movement_speed_up")
InputMap.erase_action(&"bugbot_movement_speed_down")
InputMap.erase_action(&"bugbot_place_marker")
InputMap.erase_action(&"bugbot_exit_placement")
#endregion
Input.mouse_mode = stored_mouse_mode
get_tree().paused = stored_pause_status
func _ready() -> void:
global_transform = stored_camera.global_transform
camera.current
camera.fov = stored_camera.fov
camera.near = stored_camera.near
camera.far = stored_camera.far
#endregion
func _process(_delta:float) -> void:
_calculate_movement_speed()
_calculate_rotation(_delta)
_calculate_movement()
func _physics_process(_delta:float) -> void:
_raycast_to_world()
_calculate_button_presses()
move_and_slide()
func _calculate_movement_speed() -> void:
if Input.is_action_pressed(&"bugbot_movement_speed_down") or Input.is_action_just_pressed(&"bugbot_movement_speed_down"):
if movement_speed_change_timer.is_stopped():
movement_speed /= 1.25
movement_speed_change_timer.start()
elif Input.is_action_pressed(&"bugbot_movement_speed_up") or Input.is_action_just_pressed(&"bugbot_movement_speed_up"):
if movement_speed_change_timer.is_stopped():
movement_speed *= 1.25
movement_speed_change_timer.start()
else:
movement_speed_change_timer.stop()
movement_speed = clampf(movement_speed, 0.25, 100.0)
func _calculate_rotation(_delta:float) -> void:
var rotation_velocity : Vector2 = Vector2(
Input.get_axis(&"bugbot_tilt_down", &"bugbot_tilt_up"),
Input.get_axis(&"bugbot_pan_right", &"bugbot_pan_left")) * 2.5
var mouse_velocity : Vector2 = Input.get_last_mouse_velocity()
rotation_velocity.x += mouse_velocity.y * -0.0025
rotation_velocity.y += mouse_velocity.x * -0.0025
rotation.x = clampf(rotation.x + (rotation_velocity.x * _delta), -PI/2.0 + 0.0001, PI/2.0 - 0.0001)
rotation.y += rotation_velocity.y * _delta
func _calculate_movement() -> void:
var movement_vector_lateral : Vector2 = Input.get_vector(&"bugbot_move_left", &"bugbot_move_right", &"bugbot_move_forward", &"bugbot_move_backward")
var movement_azimuth : float = Input.get_axis(&"bugbot_move_down", &"bugbot_move_up")
velocity = transform.basis * Vector3(movement_vector_lateral.x, movement_azimuth, movement_vector_lateral.y) * movement_speed
func _calculate_button_presses() -> void:
if Input.is_action_just_pressed(&"bugbot_place_marker") and raycast_collision:
print("Marker placed at ", raycast_collision["position"])
if Input.is_action_just_released(&"bugbot_exit_placement"):
exit_placement_timer.stop()
elif Input.is_action_just_pressed(&"bugbot_exit_placement"):
exit_placement_timer.start()
func _on_exit_placement_timer_timeout() -> void:
queue_free()
func _raycast_to_world():
var space : PhysicsDirectSpaceState3D = get_world_3d().direct_space_state
var query : PhysicsRayQueryParameters3D = PhysicsRayQueryParameters3D.create(global_position, global_position - global_transform.basis.z * 25.0)
query.collide_with_areas = false
query.collide_with_bodies = true
query.exclude = [get_rid()]
raycast_collision = space.intersect_ray(query)
if raycast_collision:
var collision_point : Vector3 = raycast_collision["position"]
var distance_to_collision : float = laser_beam.global_position.distance_to(collision_point)
laser_beam.scale.z = distance_to_collision
laser_beam.look_at(collision_point)
laser_beam.visible = true
else:
laser_beam.visible = false