This commit is contained in:
Redsandy
2026-01-18 20:56:24 +03:00
commit 7980e0add8
68 changed files with 1605294 additions and 0 deletions

View File

@@ -0,0 +1,87 @@
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