init
This commit is contained in:
87
scripts/enemy_health_bar.gd
Normal file
87
scripts/enemy_health_bar.gd
Normal 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
|
||||
|
||||
Reference in New Issue
Block a user