extends CharacterBody3D class_name Player3D const POINTER_TEXTURE = preload("res://common/icons/focus.svg") const POINTER_ACTION_TEXTURE = preload("res://common/icons/hand-stop.svg") @export var pointer_texture_rect : TextureRect @export var speed := 4.0 const MOUSE_SENSIVITY = 0.002 const RAY_LENGTH = 10. var cockpit_action_hovered : Interactable3D = null var query_mouse := false func _ready(): Dialogic.timeline_started.connect( func(): Input.mouse_mode = Input.MOUSE_MODE_VISIBLE ) Dialogic.timeline_ended.connect( func(): Input.mouse_mode = Input.MOUSE_MODE_CAPTURED ) func _input(event): if event is InputEventMouseMotion and Input.mouse_mode == Input.MOUSE_MODE_CAPTURED: rotate_y(-event.relative.x * MOUSE_SENSIVITY) %Camera3D.rotate_x(-event.relative.y * MOUSE_SENSIVITY) %Camera3D.rotation.x = clampf($Camera3D.rotation.x, -deg_to_rad(70), deg_to_rad(70)) query_mouse = true if event.is_action_pressed("action") and cockpit_action_hovered and cockpit_action_hovered: cockpit_action_hovered.click() func _physics_process(delta): if query_mouse: update_mouse_hovered_cockpit_actions() %PointerTexture.texture = ( POINTER_ACTION_TEXTURE if cockpit_action_hovered != null else POINTER_TEXTURE ) query_mouse = false # Add the gravity. if not is_on_floor(): velocity += get_gravity() * delta # Get the input direction and handle the movement/deceleration. # As good practice, you should replace UI actions with custom gameplay actions. var input_dir = Input.get_vector("move_left", "move_right", "move_up", "move_down") if Input.is_action_pressed("move_pointer"): input_dir.y = -1 var direction = (transform.basis * Vector3(input_dir.x, 0, input_dir.y)).normalized() if direction: velocity.x = direction.x * speed velocity.z = direction.z * speed else: velocity.x = move_toward(velocity.x, 0, speed) velocity.z = move_toward(velocity.z, 0, speed) move_and_slide() func update_mouse_hovered_cockpit_actions() -> void: var space_state = get_world_3d().direct_space_state var middle_screen = get_viewport().get_visible_rect().size / 2 var from = %Camera3D.project_ray_origin(middle_screen) var to = from + %Camera3D.project_ray_normal(middle_screen) * RAY_LENGTH var query = PhysicsRayQueryParameters3D.create(from, to) query.collide_with_areas = true var result = space_state.intersect_ray(query) if result and result.collider and result.collider is Interactable3D and result.collider.interactable: if cockpit_action_hovered and cockpit_action_hovered != result.collider: cockpit_action_hovered._on_mouse_exited() cockpit_action_hovered = result.collider cockpit_action_hovered._on_mouse_entered() else : if cockpit_action_hovered: cockpit_action_hovered._on_mouse_exited() cockpit_action_hovered = null