extends CanvasLayer @onready var background: ColorRect = $Background @onready var resume_button: Button = $Background/MenuContainer/ResumeButton @onready var quit_button: Button = $Background/MenuContainer/QuitButton # Переменные для автоматического поиска var volume_slider: HSlider = null var sensitivity_slider: HSlider = null func _ready() -> void: process_mode = Node.PROCESS_MODE_ALWAYS if background: background.visible = false print("[МЕНЮ ПАУЗЫ] Старт автоматического сканирования слайдеров...") # === АВТОМАТИЧЕСКИЙ СБОР ВСЕХ СЛАЙДЕРОВ НА СЦЕНЕ (Без путей!) === # Находим контейнер и вытаскиваем из него вообще все слайдеры var menu_container = find_child("MenuContainer", true, false) if menu_container: var all_sliders = menu_container.find_children("*", "HSlider", true, false) # Если нашли хотя бы два слайдера, распределяем их сверху вниз строго по структуре if all_sliders.size() >= 2: volume_slider = all_sliders[0] # Первый слайдер сверху — это звук sensitivity_slider = all_sliders[1] # Второй слайдер снизу — это мышь print("[МЕНЮ ПАУЗЫ] Слайдеры успешно определены! Звук: ", volume_slider.name, ", Мышь: ", sensitivity_slider.name) else: # Резервный ручной поиск по типам volume_slider = find_child("*Volume*", true, false) as HSlider if volume_slider == null: volume_slider = find_child("*Volumes*", true, false) as HSlider sensitivity_slider = find_child("SensitivitySlider", true, false) as HSlider # === АППАРАТНОЕ ПОДКЛЮЧЕНИЕ СЛАЙДЕРА ГРОМКОСТИ === if volume_slider != null: volume_slider.value = ConfigManager.volume_sfx _update_volume_text(ConfigManager.volume_sfx) if volume_slider.value_changed.is_connected(_on_volume_changed): volume_slider.value_changed.disconnect(_on_volume_changed) volume_slider.value_changed.connect(_on_volume_changed) print("[МЕНЮ ПАУЗЫ] Сигнал ГРОМКОСТИ успешно привязан программно!") else: print("[МЕНЮ ПАУЗЫ] ОШИБКА: Автомат не смог обнаружить слайдер звука!") # === АППАРАТНОЕ ПОДКЛЮЧЕНИЕ СЛАЙДЕРА МЫШИ === if sensitivity_slider != null: sensitivity_slider.value = ConfigManager.mouse_sensitivity _update_sens_text(ConfigManager.mouse_sensitivity) if sensitivity_slider.value_changed.is_connected(_on_sensitivity_changed): sensitivity_slider.value_changed.disconnect(_on_sensitivity_changed) sensitivity_slider.value_changed.connect(_on_sensitivity_changed) print("[МЕНЮ ПАУЗЫ] Сигнал ЧУВСТВИТЕЛЬНОСТИ успешно привязан программно!") else: print("[МЕНЮ ПАУЗЫ] ОШИБКА: Автомат не смог обнаружить слайдер мыши!") if resume_button: resume_button.pressed.connect(toggle_pause) if quit_button: quit_button.pressed.connect(func(): get_tree().quit()) func _unhandled_input(event: InputEvent) -> void: if event.is_action_pressed("ui_cancel") or (event is InputEventKey and event.pressed and event.keycode == KEY_ESCAPE): toggle_pause() get_viewport().set_input_as_handled() func toggle_pause() -> void: if background == null: return var is_paused = !get_tree().paused get_tree().paused = is_paused background.visible = is_paused if is_paused: # Если игра встала на паузу — освобождаем курсор для ползунков Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE) if volume_slider: volume_slider.value = ConfigManager.volume_sfx * 100.0 _update_volume_text(ConfigManager.volume_sfx) if sensitivity_slider: sensitivity_slider.value = ConfigManager.mouse_sensitivity else: # === ЖЕСТКАЯ ФИКСАЦИЯ КУРСOРА ОТ ЗАВИСАНИЯ === # Сначала сохраняем настройки на диск ConfigManager.save_settings() # Ждем два физических кадра рендеринга, чтобы все клики UI полностью угасли await get_tree().process_frame await get_tree().process_frame # И только теперь намертво прячем курсор обратно в прицел шутера! Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED) print("[МЕНЮ ПАУЗЫ] Мышь успешно заперта в прицел шутера.") func _on_volume_changed(value: float) -> void: # Если твой слайдер в редакторе настроен на шкалу от 0 до 100: # Мы принудительно делим это число на 100, чтобы получить значение от 0.0 до 1.0 для Godot! var godot_volume = value if value > 1.0: godot_volume = value / 100.0 print("[МЕНЮ ПАУЗЫ] Ползунок звука сдвинут на: ", value, "% (Для Godot: ", godot_volume, ")") # Отдаем в ConfigManager правильное дробное число (от 0.0 до 1.0) ConfigManager.apply_volume(godot_volume) # А текст на экран выводим красиво (на основе правильного дробного числа) _update_volume_text(godot_volume) func _on_sensitivity_changed(value: float) -> void: ConfigManager.mouse_sensitivity = value _update_sens_text(value) print("\n=== [ДЕБАГ СЕНСЫ] НАЧАЛО ПОИСКА КАМЕРЫ ДЛЯ ЗНАЧЕНИЯ: ", value, " ===") var player = get_tree().current_scene.find_child("PlayerCharacter", true, false) if player == null: player = get_tree().current_scene.find_child("CharacterBody3D", true, false) if player != null: for child in player.find_children("*", "Node3D", true, false): var child_name_lower = child.name.to_lower() if "camera" in child_name_lower or "sens" in child_name_lower or "holder" in child_name_lower: if "XAxisSens" in child or "X_sens" in child: child.XAxisSens = value if "YAxisSens" in child: child.YAxisSens = value print("=== [ДЕБАГ СЕНСЫ] КОНЕЦ ПОИСКА ===\n") func _update_volume_text(value: float) -> void: # Если в функцию прилетело число больше 1 (например 42), это старые проценты var checked_value = value if value > 1.0: checked_value = value / 100.0 var percent_text = str(round(checked_value * 100)) + "%" var label2 = get_node_or_null("Background/MenuContainer/Label2") if label2: label2.text = "Громкость звуков (SFX): " + percent_text func _update_sens_text(value: float) -> void: var sens_formatted = "%.3f" % value var label3 = get_node_or_null("Background/MenuContainer/Label3") if label3: label3.text = "Чувствительность мыши: " + sens_formatted