extends Sprite3D @onready var viewport: SubViewport = $SubViewport @onready var health_bar: ProgressBar = $SubViewport/HealthBar @onready var border: ColorRect = $SubViewport/Border @onready var parent_node: Node = get_parent() var shield_bar: ProgressBar = null var style_normal: StyleBoxFlat var style_aggro: StyleBoxFlat func _ready() -> void: texture = viewport.get_texture() shield_bar = $SubViewport.get_node_or_null("ShieldBar") border.visible = false style_normal = health_bar.get_theme_stylebox("fill").duplicate() style_aggro = style_normal.duplicate() style_aggro.bg_color = Color(0.2, 0.4, 0.9, 1) EventBus.target_changed.connect(_on_target_changed) EventBus.health_changed.connect(_on_health_changed) EventBus.shield_changed.connect(_on_shield_changed) _init_bars() func _init_bars() -> void: var max_health: Variant = Stats.get_stat(parent_node, "max_health") if max_health != null: health_bar.max_value = max_health health_bar.value = Stats.get_stat(parent_node, "health") var max_shield: Variant = Stats.get_stat(parent_node, "max_shield") if shield_bar: if max_shield != null and max_shield > 0: shield_bar.max_value = max_shield shield_bar.value = Stats.get_stat(parent_node, "shield") else: shield_bar.visible = false func _process(_delta: float) -> void: var player: Node = get_tree().get_first_node_in_group("player") if player and "target" in parent_node and parent_node.target == player: health_bar.add_theme_stylebox_override("fill", style_aggro) else: health_bar.add_theme_stylebox_override("fill", style_normal) func _on_health_changed(entity: Node, current: float, max_val: float) -> void: if entity != parent_node: return health_bar.max_value = max_val health_bar.value = current func _on_shield_changed(entity: Node, current: float, max_val: float) -> void: if entity != parent_node or shield_bar == null: return shield_bar.max_value = max_val shield_bar.value = current func _on_target_changed(_player: Node, target: Node) -> void: border.visible = (target == get_parent())