Roblox · Интерфейсы
Над каждым противником и NPC — имя и полоска здоровья: уменьшается плавно, меняет цвет от зелёного к красному, показывает числа. Один скрипт сам находит всех мобов, даже появившихся позже.
Синим — что нужно создать.
ReplicatedStorage └─ HealthBar (BillboardGui) — шаблон: Size {4,0},{1.2,0}, StudsOffset 0, 2.5, 0, AlwaysOnTop ├─ NameLabel (TextLabel) — имя сверху └─ Background (Frame) — тёмная подложка ├─ Bar (Frame) — цветная полоса, Size {1,0},{1,0} └─ HealthText (TextLabel) — числа, ZIndex 2 StarterPlayer → StarterPlayerScripts └─ HealthBarLocal (LocalScript) Workspace └─ Dummy (Model) — манекен для проверки (по желанию) ├─ ClickDetector (ClickDetector) └─ ClickDamage (Script)
Где: StarterPlayer → StarterPlayerScripts · LocalScript
Зачем: Полоски над всеми мобами.
-- игроки
local Players = game:GetService("Players")
-- здесь шаблон полоски
local RS = game:GetService("ReplicatedStorage")
-- плавное уменьшение
local TweenService = game:GetService("TweenService")
-- шаблон BillboardGui
local template = RS:WaitForChild("HealthBar")
-- false — полоска появится только после первого удара
local SHOW_WHEN_FULL = true
-- много здоровья
local GREEN = Color3.fromRGB(80, 220, 90)
-- половина
local YELLOW = Color3.fromRGB(250, 210, 60)
-- мало
local RED = Color3.fromRGB(235, 60, 60)
-- цвет по доле здоровья от 0 до 1
local function ColorFor(k)
-- от жёлтого к зелёному
if k > 0.5 then return YELLOW:Lerp(GREEN, (k - 0.5) * 2) end
-- от красного к жёлтому
return RED:Lerp(YELLOW, k * 2)
-- конец функции
end
-- повесить полоску на одного моба
local function Attach(humanoid)
-- модель моба
local model = humanoid.Parent
-- Humanoid не в модели
if not model or not model:IsA("Model") then return end
-- игрокам полоска не нужна
if Players:GetPlayerFromCharacter(model) then return end
-- атрибут NoHealthBar — без полоски (мирные жители)
if model:GetAttribute("NoHealthBar") then return end
-- над чем висеть
local head = model:FindFirstChild("Head") or model:WaitForChild("Head", 3) or model:FindFirstChild("HumanoidRootPart")
-- не к чему крепить или уже есть
if not head or head:FindFirstChild("HealthBar") then return end
-- прячем стандартное имя и здоровье
humanoid.DisplayDistanceType = Enum.HumanoidDisplayDistanceType.None
-- копия шаблона
local gui = template:Clone()
-- висит над головой
gui.Adornee = head
-- удалится вместе с мобом
gui.Parent = head
-- цветная полоса
local bar = gui.Background.Bar
-- «45 / 60»
local text = gui.Background.HealthText
-- имя моба
gui.NameLabel.Text = humanoid.DisplayName ~= "" and humanoid.DisplayName or model.Name
-- обновить полоску
local function Update()
-- доля здоровья
local k = math.clamp(humanoid.Health / math.max(humanoid.MaxHealth, 1), 0, 1)
-- плавно укорачиваем
TweenService:Create(bar, TweenInfo.new(0.2), {Size = UDim2.fromScale(k, 1)}):Play()
-- цвет
bar.BackgroundColor3 = ColorFor(k)
-- числа
text.Text = math.ceil(humanoid.Health) .. " / " .. math.ceil(humanoid.MaxHealth)
-- погиб — прячем
gui.Enabled = humanoid.Health > 0 and (SHOW_WHEN_FULL or k < 1)
-- конец функции
end
-- урон или лечение
humanoid.HealthChanged:Connect(Update)
-- сменился максимум
humanoid:GetPropertyChangedSignal("MaxHealth"):Connect(Update)
-- сразу
Update()
-- конец функции
end
-- мобы, которые уже есть
for _, obj in ipairs(workspace:GetDescendants()) do
-- вешаем полоску
if obj:IsA("Humanoid") then task.spawn(Attach, obj) end
-- конец перебора
end
-- появился новый объект
workspace.DescendantAdded:Connect(function(obj)
-- это моб — вешаем полоску
if obj:IsA("Humanoid") then task.spawn(Attach, obj) end
-- конец функции
end)Где: Workspace → Dummy · Script
Зачем: Манекен для проверки: урон по клику.
-- манекен для проверки
local dummy = script.Parent
-- его здоровье
local humanoid = dummy:WaitForChild("Humanoid")
-- клик мышью
local clicker = dummy:WaitForChild("ClickDetector")
-- клик по манекену
clicker.MouseClick:Connect(function()
-- −15 здоровья
humanoid:TakeDamage(15)
-- конец функции
end)
-- медленно лечится
while true do
-- раз в секунду
task.wait(1)
-- +2, пока жив
if humanoid.Health > 0 then humanoid.Health = math.min(humanoid.Health + 2, humanoid.MaxHealth) end
-- конец цикла
endЗапусти Play (или Run) и убедись: