Menu
CoddyTech

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 icon

Challenge

Easy

At the end of the script, write setupDummy(dummy):

  1. On the Humanoid's HealthChanged, size dummy.HealthBar.Back.Fill to the health left.
  2. On Died: keep dummy:GetPivot(), wait 0.5 seconds, destroy it, wait Settings.DummyRespawn, clone ServerStorage.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)
quiz iconTest yourself

This lesson includes a short quiz. Start the lesson to answer it and track your progress.

All lessons in Roblox Game: Battlegrounds