Training Dummy
Lesson 5 of 20 in Coddy's Roblox Game: Battlegrounds course.
The dummy needs two things to be a training dummy: a health bar, and to come back when it is beaten.
Its HealthBar is a BillboardGui with a green Fill inside a dark Back. UDim2.fromScale(health / MaxHealth, 1) makes the fill as wide as the health left.
When its Humanoid Died, remember where it stood (GetPivot), remove it, wait Settings.DummyRespawn seconds and put a fresh copy from ServerStorage in its place. The fresh one needs the same setup, so the setup is a function that calls itself for the new dummy:
local function setupDummy(dummy)
-- health bar, and on Died: ... setupDummy(fresh)
end
setupDummy(workspace.Dummy)Challenge
EasyAt the end of the script, write setupDummy(dummy):
- On the Humanoid's
HealthChanged, sizedummy.HealthBar.Back.Fillto the health left. - On
Died: keepdummy:GetPivot(), wait 0.5 seconds, destroy it, waitSettings.DummyRespawn, cloneServerStorage.Dummy, pivot it there, parent it to workspace, and set it up.
Call it for workspace.Dummy. Press Play, then Check.
Try it yourself
local Players = game:GetService("Players")
local ServerStorage = game:GetService("ServerStorage")
local Settings = require(game.ReplicatedStorage.Settings)
local lastSwing = {} -- player -> when they last swung
-- Roblox's own sword animations
local slash = Instance.new("Animation")
slash.AnimationId = "rbxassetid://522635514"
print("Swords deal " .. Settings.SwordDamage .. " damage")
-- A swing: the animation, then everyone in the box in front of you is hit
local function swing(player)
local character = player.Character
local root = character and character:FindFirstChild("HumanoidRootPart")
if not root or character.Humanoid.Health <= 0 then
return
end
local now = time()
if lastSwing[player] and now - lastSwing[player] < Settings.SwingCooldown then
return
end
lastSwing[player] = now
character.Humanoid.Animator:LoadAnimation(slash):Play()
-- the box in front of you, never your own body
local params = OverlapParams.new()
params.FilterDescendantsInstances = { character }
local box = root.CFrame * CFrame.new(0, 0, -3)
local hit = {} -- each humanoid once per swing
for _, part in workspace:GetPartBoundsInBox(box, Settings.HitboxSize, params) do
local humanoid = part.Parent:FindFirstChildOfClass("Humanoid")
if humanoid and not hit[humanoid] then
hit[humanoid] = true
humanoid:TakeDamage(Settings.SwordDamage)
end
end
end
-- Every player gets Kills on the leaderboard, and a sword every life
Players.PlayerAdded:Connect(function(player)
local leaderstats = Instance.new("Folder")
leaderstats.Name = "leaderstats"
leaderstats.Parent = player
local kills = Instance.new("IntValue")
kills.Name = "Kills"
kills.Parent = leaderstats
player.CharacterAdded:Connect(function()
local sword = ServerStorage.Sword:Clone()
sword.Parent = player.Backpack
sword.Activated:Connect(function()
swing(player)
end)
end)
end)
This lesson includes a short quiz. Start the lesson to answer it and track your progress.