MultiplayerFighter
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

86 lines
2.4 KiB

extends Label3D
class_name DamageNumber
## Floating damage number that animates upward and fades out
@export var float_speed: float = 3.0
@export var lifetime: float = 1.8
@export var spread: float = 0.7 # Random horizontal spread
var _elapsed: float = 0.0
var _velocity: Vector3 = Vector3.ZERO
var _initial_scale: float = 1.5
func _ready():
# Random horizontal spread
_velocity = Vector3(
randf_range(-spread, spread),
float_speed,
randf_range(-spread, spread)
)
# Billboard mode so it always faces camera
billboard = BaseMaterial3D.BILLBOARD_ENABLED
# Start with full opacity
modulate.a = 1.0
# Larger initial scale for impact
scale = Vector3.ONE * 0.5
func _process(delta):
_elapsed += delta
# Move upward with velocity
position += _velocity * delta
_velocity.y -= delta * 1.5 # Slight gravity effect
# Fade out over lifetime (keep visible longer, then quick fade)
var fade_progress = _elapsed / lifetime
if fade_progress < 0.7:
modulate.a = 1.0
else:
var fade_amount = (fade_progress - 0.7) / 0.3
modulate.a = 1.0 - fade_amount
# Pop animation - quick scale up, then gentle scale down
if fade_progress < 0.15:
# Quick pop up
var scale_progress = fade_progress / 0.15
var target_scale = _initial_scale * (0.5 + (0.5 * scale_progress))
scale = Vector3.ONE * target_scale
elif fade_progress < 0.3:
# Slight bounce/overshoot
var bounce_progress = (fade_progress - 0.15) / 0.15
var overshoot = sin(bounce_progress * PI) * 0.15
var target_scale = _initial_scale * (1.0 + overshoot)
scale = Vector3.ONE * target_scale
else:
# Gentle shrink
var shrink_progress = (fade_progress - 0.3) / 0.7
var target_scale = _initial_scale * (1.0 - (shrink_progress * 0.3))
scale = Vector3.ONE * target_scale
# Delete when lifetime expired
if _elapsed >= lifetime:
queue_free()
## Set the damage number text and color
func set_damage(amount: float, was_blocked: bool = false):
text = str(int(amount))
if was_blocked:
# Bright yellow/orange for blocked damage with strong contrast
modulate = Color(1.0, 0.9, 0.0) # Bright yellow
outline_modulate = Color(0.3, 0.15, 0.0) # Dark brown/black outline
else:
# Vibrant red for normal damage with black outline
modulate = Color(1.0, 0.15, 0.15) # Bright red
outline_modulate = Color(0.1, 0.0, 0.0) # Almost black outline
# Much larger and bolder
outline_size = 16
font_size = 72
# Add depth with larger outline
pixel_size = 0.002 # Slightly larger pixels for better visibility