почин диалогов, пратиклы от выстлеров
This commit is contained in:
@@ -3,7 +3,6 @@
|
||||
[ext_resource type="Script" uid="uid://in2mxlslr7en" path="res://addons/dialoge/script/DialogueUI.gd" id="1_gunyw"]
|
||||
|
||||
[sub_resource type="LabelSettings" id="LabelSettings_gunyw"]
|
||||
font_color = Color(0, 0, 0, 1)
|
||||
|
||||
[node name="DialogueUI" type="CanvasLayer" unique_id=996459414]
|
||||
script = ExtResource("1_gunyw")
|
||||
|
||||
@@ -7,56 +7,125 @@ extends CanvasLayer
|
||||
|
||||
var current_dialogue_lines: Array = []
|
||||
var current_line_index: int = 0
|
||||
var player_ref: Node3D = null
|
||||
var is_active: bool = false
|
||||
|
||||
# --- НАШИ НОВЫЕ ПЕРЕМЕННЫЕ ДЛЯ ЗАМОРОЗКИ ВЗГЛЯДА ---
|
||||
var camera_node: Camera3D = null
|
||||
var saved_camera_rotation: Vector3 = Vector3.ZERO
|
||||
var is_camera_locked: bool = false
|
||||
|
||||
func _ready():
|
||||
# Изначально скрываем и окно диалога, и саму подсказку "Press E"
|
||||
dialogue_box.visible = false
|
||||
if press_e_label:
|
||||
press_e_label.visible = false
|
||||
if dialogue_box: dialogue_box.visible = false
|
||||
if press_e_label: press_e_label.visible = false
|
||||
|
||||
func start_dialogue(lines: Array):
|
||||
# Как только диалог начался — подсказку "Press E" нужно СРАЗУ убрать с экрана
|
||||
hide_prompt()
|
||||
|
||||
current_dialogue_lines = lines
|
||||
current_line_index = 0
|
||||
dialogue_box.visible = true
|
||||
if dialogue_box: dialogue_box.visible = true
|
||||
is_active = true
|
||||
|
||||
player_ref = get_tree().current_scene.find_child("PlayerCharacter", true, false)
|
||||
if player_ref:
|
||||
# Блокируем стрельбу
|
||||
var wm = player_ref.find_child("WeaponManager", true, false)
|
||||
if wm:
|
||||
if "canUseWeapon" in wm: wm.canUseWeapon = false
|
||||
if wm.has_method("disable_weapons_for_dialogue"): wm.disable_weapons_for_dialogue()
|
||||
|
||||
# --- ЖЕСТКАЯ ФИКСАЦИЯ УГЛА КАМЕРЫ ---
|
||||
# Находим 3D-камеру внутри игрока
|
||||
camera_node = player_ref.find_child("Camera3D", true, false)
|
||||
if camera_node == null:
|
||||
camera_node = player_ref.find_child("PlayerCamera", true, false)
|
||||
|
||||
if camera_node:
|
||||
# Запоминаем точный угол, куда смотрел игрок в момент нажатия Е
|
||||
saved_camera_rotation = camera_node.rotation
|
||||
is_camera_locked = true
|
||||
print("[UI] Угол камеры успешно сохранен: ", saved_camera_rotation)
|
||||
|
||||
Input.mouse_mode = Input.MOUSE_MODE_VISIBLE
|
||||
show_current_line()
|
||||
|
||||
# Физический цикл интерфейса, который работает пока открыто окно диалога
|
||||
func _process(_delta: float) -> void:
|
||||
# Пока диалог активен, мы КАЖДЫЙ КАДР принудительно возвращаем камере сохраненный угол,
|
||||
# полностью перебивая любые попытки ассета уронить взгляд в пол!
|
||||
if is_camera_locked and camera_node != null and is_instance_valid(camera_node):
|
||||
camera_node.rotation = saved_camera_rotation
|
||||
|
||||
func show_current_line():
|
||||
if current_line_index < current_dialogue_lines.size():
|
||||
var line_data = current_dialogue_lines[current_line_index]
|
||||
name_label.text = line_data.get("name", "NPC")
|
||||
text_label.text = line_data.get("text", "")
|
||||
if name_label: name_label.text = line_data.get("name", "NPC")
|
||||
if text_label: text_label.text = line_data.get("text", "")
|
||||
else:
|
||||
# Перед закрытием просим Сталкера обнулить статус активности
|
||||
var current_scene = get_tree().current_scene
|
||||
if current_scene:
|
||||
var npc = current_scene.find_child("StaticBody3D", true, false)
|
||||
if npc == null: npc = current_scene.find_child("bot", true, false)
|
||||
if npc and "_restore_player_control" in npc:
|
||||
npc._restore_player_control()
|
||||
if "is_dialogue_active" in npc: npc.is_dialogue_active = false
|
||||
|
||||
end_dialogue()
|
||||
|
||||
func _input(event):
|
||||
if dialogue_box.visible:
|
||||
var is_mouse_click = event is InputEventMouseButton and event.pressed and event.button_index == MOUSE_BUTTON_LEFT
|
||||
var is_accept = event.is_action_pressed("ui_accept")
|
||||
var is_e_key = event is InputEventKey and event.pressed and event.keycode == KEY_E
|
||||
func _unhandled_input(event: InputEvent) -> void:
|
||||
if is_active and dialogue_box and dialogue_box.visible:
|
||||
var is_click = event is InputEventMouseButton and event.pressed and event.button_index == MOUSE_BUTTON_LEFT
|
||||
var is_space = event is InputEventKey and event.pressed and event.keycode == KEY_SPACE
|
||||
|
||||
if is_mouse_click or is_accept or is_e_key:
|
||||
if is_click or is_space:
|
||||
current_line_index += 1
|
||||
show_current_line()
|
||||
# Перехватываем ввод, чтобы клики мыши при листании не вызывали стрельбу в шутере
|
||||
get_viewport().set_input_as_handled()
|
||||
|
||||
func end_dialogue():
|
||||
dialogue_box.visible = false
|
||||
Input.mouse_mode = Input.MOUSE_MODE_CAPTURED
|
||||
|
||||
# Функция для показа подсказки
|
||||
func show_prompt() -> void:
|
||||
if press_e_label and not dialogue_box.visible:
|
||||
press_e_label.visible = true
|
||||
print("[UI] Подсказка 'Press E' успешно включена на экране.")
|
||||
|
||||
# Функция для скрытия подсказки
|
||||
func hide_prompt() -> void:
|
||||
if press_e_label:
|
||||
is_active = false
|
||||
if dialogue_box:
|
||||
dialogue_box.visible = false
|
||||
if press_e_label:
|
||||
press_e_label.visible = false
|
||||
print("[UI] Подсказка 'Press E' скрыта.")
|
||||
|
||||
is_camera_locked = false
|
||||
|
||||
# Даем игре фору в два физических кадра, чтобы финальный клик мышки полностью угас
|
||||
await get_tree().process_frame
|
||||
await get_tree().process_frame
|
||||
|
||||
# --- БРОНЕБОЙНЫЙ РАЗБЛОК СТРЕЛЬБЫ, ПЕРЕЗАРЯДКИ И КОЛЕСИКА ОРУЖИЯ ---
|
||||
if player_ref:
|
||||
var wm = player_ref.find_child("WeaponManager", true, false)
|
||||
if wm:
|
||||
# 1. Возвращаем базовые флаги использования и смены пушек
|
||||
if "canUseWeapon" in wm: wm.canUseWeapon = true
|
||||
if "canChangeWeapons" in wm: wm.canChangeWeapons = true
|
||||
if "canReload" in wm: wm.canReload = true
|
||||
|
||||
# 2. Вызываем ВСЕ возможные методы включения оружия, какие заложил автор ассета:
|
||||
if wm.has_method("enable_weapons_after_dialogue"):
|
||||
wm.enable_weapons_after_dialogue()
|
||||
elif wm.has_method("enable_weapons"):
|
||||
wm.enable_weapons()
|
||||
elif wm.has_method("activate_weapons"):
|
||||
wm.activate_weapons()
|
||||
|
||||
# 3. Принудительно заставляем HUD и пушку обновиться, чтобы вернуть её в руки
|
||||
if wm.has_method("displayStats"):
|
||||
wm.displayStats()
|
||||
if "cW" in wm and wm.cW != null and wm.has_method("changeWeapon"):
|
||||
# Насильно заставляем персонажа достать текущее оружие обратно
|
||||
wm.changeWeapon(wm.weaponStack[wm.weaponIndex])
|
||||
|
||||
Input.mouse_mode = Input.MOUSE_MODE_CAPTURED
|
||||
print("[UI] Диалог чисто закрыт. Оружие, перезарядка и колесико принудительно возвращены в строй!")
|
||||
|
||||
func show_prompt() -> void:
|
||||
if press_e_label and (dialogue_box == null or not dialogue_box.visible):
|
||||
press_e_label.visible = true
|
||||
|
||||
func hide_prompt() -> void:
|
||||
if press_e_label: press_e_label.visible = false
|
||||
|
||||
Reference in New Issue
Block a user