extends Node3D class_name EnemyHealthBar # Скрипт для отображения полоски здоровья над врагом @onready var background_bar: MeshInstance3D = $BackgroundBar @onready var health_bar: MeshInstance3D = $HealthBar var unit: Unit = null var bar_width: float = 3.0 var bar_height: float = 0.2 func _ready(): # Находим родительский Unit (враг) unit = get_parent() as Unit if unit: # Подключаемся к сигналу изменения здоровья unit.health_changed.connect(_on_health_changed) # Изначально скрываем полоску (если здоровье 100%) update_visibility() update_health_bar() else: print("EnemyHealthBar: Не найден Unit!") # Убеждаемся, что узлы найдены if not background_bar: print("EnemyHealthBar: Не найден BackgroundBar!") if not health_bar: print("EnemyHealthBar: Не найден HealthBar!") func _process(_delta): # Поворачиваем полоску к камере var camera = get_viewport().get_camera_3d() if camera and visible: # BoxMesh по умолчанию ориентирован правильно # Поворачиваем полоску так, чтобы она была обращена к камере # Используем только горизонтальный поворот (по оси Y), чтобы полоска оставалась горизонтальной var direction_to_camera = (camera.global_position - global_position).normalized() if direction_to_camera.length() > 0.01: var horizontal_direction = direction_to_camera horizontal_direction.y = 0 horizontal_direction = horizontal_direction.normalized() if horizontal_direction.length() > 0.01: # Поворачиваем только по оси Y var angle = atan2(horizontal_direction.x, horizontal_direction.z) rotation.y = angle # Обновляем полоску после поворота (чтобы позиция была правильной) if unit: update_health_bar() func _on_health_changed(new_health: float): update_health_bar() update_visibility() func update_health_bar(): if not unit or not health_bar: return var health_percent = clamp(unit.health / unit.max_health, 0.0, 1.0) # Масштабируем полоску здоровья в зависимости от процента # Убеждаемся, что масштаб всегда положительный и достаточно большой для видимости var scale_x = max(health_percent, 0.05) # Минимум 0.05 для лучшей видимости health_bar.scale.x = scale_x # Смещаем полоску влево, чтобы она уменьшалась справа налево # Используем локальные координаты относительно центра # Центр полоски должен быть в центре, поэтому смещаем на половину разницы var offset = -(bar_width * (1.0 - health_percent)) / 2.0 health_bar.position.x = offset # Убеждаемся, что зеленая полоска немного впереди красной для правильного отображения health_bar.position.z = 0.01 func update_visibility(): if not unit: visible = false return # Показываем полоску только если здоровье меньше 100% var should_show = unit.health < unit.max_health visible = should_show if background_bar: background_bar.visible = should_show if health_bar: health_bar.visible = should_show