Files
acrion-rog-client/scripts/enemy_health_bar.gd
Redsandy 7980e0add8 init
2026-01-18 20:56:24 +03:00

88 lines
3.6 KiB
GDScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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