Проблема
Вы хотите, чтобы при попадании урон отображался в виде плавающих чисел.

Решение
Существует несколько способов реализовать это. Например, можно использовать растровый шрифт и создавать изображение для каждого числа, а затем отображать его с помощью узла Sprite2D
.
Однако в этом примере мы будем использовать узел Label
(названный «FCT»). Это позволит легко менять шрифт, а также отображать число в виде строки или, например, сообщение «промах».
Добавьте ресурс LabelSettings
и выберите подходящий шрифт. В данном случае используется «Xolonium.ttf» с размером 28 и черной обводкой в 4 пикселя.
Затем добавьте скрипт к этому элементу.
extends Label
func show_value(value, travel, duration, spread, crit=false):
Когда создается плавающий текст, вызывается функция, которая задает его параметры:
- value – число или строка, которые нужно отобразить
- travel – вектор направления движения
- duration – время, в течение которого текст будет виден
- spread – случайное отклонение движения в указанном диапазоне
- crit – если true, это означает, что удар был критическим
Что делает функция:
text = value
var movement = travel.rotated(rand_range(-spread/2, spread/2))
rect_pivot_offset = rect_size / 2
Сначала задается значение текста и случайное направление движения (например, в пределах +/- 90 градусов). Если планируется анимация масштаба, центр элемента смещается, чтобы масштаб изменялся относительно середины.
Проверь свои знания в нашем бесплатном ТЕСТЕ по Godot! Узнай, насколько хорошо ты его знаешь!
$Tween.interpolate_property(self, "rect_position",
rect_position, rect_position + movement,
duration, Tween.TRANS_LINEAR, Tween.EASE_IN_OUT)
$Tween.interpolate_property(self, "modulate:a",
1.0, 0.0, duration,
Tween.TRANS_LINEAR, Tween.EASE_IN_OUT)
Затем анимируются две характеристики:
- rect_position – отвечает за перемещение текста
- modulate.a – управляет прозрачностью
if crit:
modulate = Color(1, 0, 0)
$Tween.interpolate_property(self, "rect_scale",
rect_scale*2, rect_scale,
0.4, Tween.TRANS_BACK, Tween.EASE_IN)
Если удар был критическим, цвет изменится, а также будет добавлена анимация масштаба для большего эффекта. В данном случае цвет жестко задан как красный, но лучше сделать его настраиваемым.
$Tween.start()
yield($Tween, "tween_all_completed")
queue_free()
В конце запускается анимация, после завершения которой элемент удаляется.
Менеджер плавающего текста
Теперь создадим небольшой узел для управления появлением и размещением плавающего текста. Этот узел будет привязан к игровым объектам, которым нужен эффект плавающего текста.
Этот узел – Node2D с названием «FCTManager». Он использует следующий скрипт:
extends Node2D
var FCT = preload("res://FCT.tscn")
export var travel = Vector2(0, -80)
export var duration = 2
export var spread = PI/2
func show_value(value, crit=false):
var fct = FCT.instance()
add_child(fct)
fct.show_value(str(value), travel, duration, spread, crit)
В Inspector можно настроить параметры. Метод show_value() создает плавающие числа и задает их свойства.
В игровом юните нужно добавить экземпляр этого узла и разместить его в нужном месте. Затем в методе take_damage() добавить вызов эффекта:
$FCTManager.show_value(dmg, crit)
Оптимизация
Если в игре много врагов или пуль, постоянное создание и удаление плавающего текста может повлиять на производительность. В таком случае можно заранее создать фиксированное количество текстовых элементов и просто скрывать/показывать их вместо удаления.

