this code.
--[[
Square Voxel-Style Stamina Bar HUD + Sprint System for Roblox
- Place this LocalScript in StarterPlayerScripts.
- Shows a square, blue, voxel-style stamina bar at the bottom left.
- The stamina bar background is very long and mostly offscreen, but the filled blocks are always visible.
- Sprinting drains stamina, walking restores it.
- Sprinting: Hold Shift (or mobile button).
- Sprinting plays a run sound.
- Sprint speed is always +20 above the player's current WalkSpeed.
- If stamina runs out, player is exhausted and must wait longer for regen to start, and regen is slower.
- The stamina value is displayed below the bar, outside the bar.
- The stamina blocks' position is easily modifiable via a single variable.
]]
local Players = game:GetService("Players")
local TweenService = game:GetService("TweenService")
local UserInputService = game:GetService("UserInputService")
local RunService = game:GetService("RunService")
local LocalPlayer = Players.LocalPlayer
-- Stamina settings
local MAX_STAMINA = 100
local STAMINA_DRAIN_RATE = 30 -- per second
local STAMINA_RECOVER_RATE = 12 -- per second (normal)
local STAMINA_RECOVER_RATE_EXHAUSTED = 6 -- per second (after running out)
local STAMINA_REGEN_DELAY = 1.2 -- seconds before regen starts (normal)
local STAMINA_REGEN_DELAY_EXHAUSTED = 2.5 -- seconds before regen starts (after running out)
local MIN_STAMINA_TO_SPRINT = 10
-- Bar style
local BAR_BLOCKS = 8
local BLOCK_SIZE = UDim2.new(0, 18, 0, 18)
local BLOCK_SPACING = 4
local BAR_WIDTH = BAR_BLOCKS * BLOCK_SIZE.X.Offset + (BAR_BLOCKS-1)*BLOCK_SPACING
local BAR_HEIGHT = BLOCK_SIZE.Y.Offset + 12
local STAMINA_BAR_MARGIN_X = 24
local STAMINA_BAR_MARGIN_Y = 24
-- Offscreen background settings
local BG_TOTAL_WIDTH = 320 -- very long, most of it offscreen
local BG_VISIBLE_X = STAMINA_BAR_MARGIN_X -- where the visible part starts
-- Sound assets (replace with your own if desired)
local RUN_SOUND_ID = "rbxassetid://9118828562" -- Example run sound
-- UI Colors (cartoony blue style)
local BAR_BG_COLOR = Color3.fromRGB(20, 30, 60)
local BLOCK_FULL_COLOR = Color3.fromRGB(80, 200, 255)
local BLOCK_EMPTY_COLOR = Color3.fromRGB(60, 120, 180)
local BLOCK_OUTLINE_COLOR = Color3.fromRGB(80, 200, 255)
local BLOCK_CORNER_RADIUS = UDim.new(0, 6)
local GLOW_COLOR = Color3.fromRGB(80, 200, 255)
local GLOW_TRANSPARENCY = 0.4
local GLOW_SIZE_OFFSET = 8
local GLOW_IMAGE = "rbxassetid://5107168713"
local BAR_TEXT_COLOR = Color3.fromRGB(255, 255, 255)
local BAR_TEXT_STROKE = GLOW_COLOR
-- Easily modifiable stamina block position (relative to barBg)
-- Change this to move the blocks as a group!
local BLOCKS_POSITION = UDim2.new(-0.015, BG_TOTAL_WIDTH - (BAR_WIDTH + 8) + 6, 0, 6)
-- Utility: Create a voxel block
local function createVoxelBlock(parent, index)
local block = Instance.new("Frame")
block.Name = "VoxelBlock"..index
block.Size = BLOCK_SIZE
block.BackgroundColor3 = BLOCK_EMPTY_COLOR
block.BorderSizePixel = 0
block.BackgroundTransparency = 0.2
block.Parent = parent
block.ZIndex = 2
-- Outline
local outline = Instance.new("UIStroke")
outline.Color = BLOCK_OUTLINE_COLOR
outline.Thickness = 2
outline.Parent = block
-- Rounded corners
local corner = Instance.new("UICorner")
corner.CornerRadius = BLOCK_CORNER_RADIUS
corner.Parent = block
-- Glow/shadow
local glow = Instance.new("ImageLabel")
glow.Name = "Glow"
glow.BackgroundTransparency = 1
glow.Image = GLOW_IMAGE
glow.ImageColor3 = GLOW_COLOR
glow.ImageTransparency = GLOW_TRANSPARENCY
glow.Size = UDim2.new(1, GLOW_SIZE_OFFSET, 1, GLOW_SIZE_OFFSET)
glow.Position = UDim2.new(0, -GLOW_SIZE_OFFSET//2, 0, -GLOW_SIZE_OFFSET//2)
glow.ZIndex = 1
glow.Parent = block
-- Highlight (shine, fully transparent for now)
local highlight = Instance.new("Frame")
highlight.Name = "Highlight"
highlight.Size = UDim2.new(0.6, 0, 0.25, 0)
highlight.Position = UDim2.new(0.4, 0, 0.08, 0)
highlight.BackgroundTransparency = 1
highlight.BackgroundColor3 = Color3.fromRGB(255, 255, 255)
highlight.BorderSizePixel = 0
highlight.ZIndex = 3
local highlightCorner = Instance.new("UICorner")
highlightCorner.CornerRadius = UDim.new(1, 0)
highlightCorner.Parent = highlight
highlight.Parent = block
return block
end
-- Utility: Create the stamina bar GUI (square, voxel style, offscreen, long background)
local function createStaminaBar()
-- Remove old bar if exists
local old = LocalPlayer.PlayerGui:FindFirstChild("StaminaBarGui")
if old then old:Destroy() end
local screenGui = Instance.new("ScreenGui")
screenGui.Name = "StaminaBarGui"
screenGui.ResetOnSpawn = false
screenGui.IgnoreGuiInset = true
screenGui.Parent = LocalPlayer:WaitForChild("PlayerGui")
-- Bar background (very long, mostly offscreen)
local barBg = Instance.new("Frame")
barBg.Name = "BarBg"
barBg.Size = UDim2.new(0, BG_TOTAL_WIDTH, 0, BAR_HEIGHT)
barBg.Position = UDim2.new(0, STAMINA_BAR_MARGIN_X - (BG_TOTAL_WIDTH - BAR_WIDTH - 8), 1, -(BAR_HEIGHT + STAMINA_BAR_MARGIN_Y))
barBg.AnchorPoint = Vector2.new(0, 0)
barBg.BackgroundColor3 = BAR_BG_COLOR
barBg.BackgroundTransparency = 0.15
barBg.BorderSizePixel = 0
barBg.Parent = screenGui
barBg.ZIndex = 2
local barCorner = Instance.new("UICorner")
barCorner.CornerRadius = UDim.new(0, 10)
barCorner.Parent = barBg
-- Border glow
local borderGlow = Instance.new("ImageLabel")
borderGlow.Name = "BorderGlow"
borderGlow.BackgroundTransparency = 1
borderGlow.Image = GLOW_IMAGE
borderGlow.ImageColor3 = GLOW_COLOR
borderGlow.ImageTransparency = 0.7
borderGlow.Size = UDim2.new(1, 16, 1, 16)
borderGlow.Position = UDim2.new(0, -8, 0, -8)
borderGlow.ZIndex = 1
borderGlow.Parent = barBg
-- Bar outline
local outline = Instance.new("UIStroke")
outline.Color = BLOCK_OUTLINE_COLOR
outline.Thickness = 2
outline.Parent = barBg
-- Voxel blocks (always visible, positioned at the visible end of the bar)
local blocks = {}
for i = 1, BAR_BLOCKS do
local block = createVoxelBlock(barBg, i)
block.Position = UDim2.new(
BLOCKS_POSITION.X.Scale,
BLOCKS_POSITION.X.Offset + (i-1)*(BLOCK_SIZE.X.Offset + BLOCK_SPACING),
BLOCKS_POSITION.Y.Scale,
BLOCKS_POSITION.Y.Offset
)
blocks[i] = block
end
-- "STAMINA" label (above bar, at visible end)
local label = Instance.new("TextLabel")
label.Name = "StaminaLabel"
label.Text = "STAMINA"
label.Font = Enum.Font.FredokaOne
label.TextColor3 = BAR_TEXT_COLOR
label.TextStrokeTransparency = 0.2
label.TextStrokeColor3 = BAR_TEXT_STROKE
label.TextScaled = true
label.Size = UDim2.new(0, BAR_WIDTH + 8, 0, 18)
label.Position = UDim2.new(0, BG_TOTAL_WIDTH - (BAR_WIDTH + 8), 0, -20)
label.BackgroundTransparency = 1
label.Parent = barBg
label.ZIndex = 3
-- Label glow
local labelGlow = Instance.new("ImageLabel")
labelGlow.Name = "LabelGlow"
labelGlow.BackgroundTransparency = 1
labelGlow.Image = GLOW_IMAGE
labelGlow.ImageColor3 = GLOW_COLOR
labelGlow.ImageTransparency = 0.7
labelGlow.Size = UDim2.new(0, BAR_WIDTH + 8, 0, 18)
labelGlow.Position = UDim2.new(0, BG_TOTAL_WIDTH - (BAR_WIDTH + 8), 0, -20)
labelGlow.ZIndex = 2
labelGlow.Parent = barBg
-- Value label (below the visible bar, outside the bar)
local valueLabel = Instance.new("TextLabel")
valueLabel.Name = "ValueLabel"
valueLabel.Text = tostring(MAX_STAMINA)
valueLabel.Font = Enum.Font.FredokaOne
valueLabel.TextColor3 = BAR_TEXT_COLOR
valueLabel.TextStrokeTransparency = 0.2
valueLabel.TextStrokeColor3 = BAR_TEXT_STROKE
valueLabel.TextScaled = true
valueLabel.Size = UDim2.new(0, BAR_WIDTH + 8, 0, 18)
valueLabel.Position = UDim2.new(0, BG_TOTAL_WIDTH - (BAR_WIDTH + 8), 0, BAR_HEIGHT + 4)
valueLabel.BackgroundTransparency = 1
valueLabel.Parent = barBg
valueLabel.ZIndex = 3
return {
gui = screenGui,
barBg = barBg,
blocks = blocks,
label = label,
labelGlow = labelGlow,
borderGlow = borderGlow,
valueLabel = valueLabel,
outline = outline,
}
end
-- Update the stamina bar blocks based on current stamina
local function updateStaminaBar(bar, stamina)
local percent = math.clamp(stamina / MAX_STAMINA, 0, 1)
local blocks = bar.blocks
local staminaPerBlock = MAX_STAMINA / #blocks
for i, block in ipairs(blocks) do
if stamina >= i * staminaPerBlock then
block.BackgroundColor3 = BLOCK_FULL_COLOR
block.BackgroundTransparency = 0
if block:FindFirstChild("Glow") then
block.Glow.ImageColor3 = GLOW_COLOR
block.Glow.ImageTransparency = GLOW_TRANSPARENCY
end
elseif stamina > (i-1) * staminaPerBlock then
-- Partial block: use a lighter color
block.BackgroundColor3 = BLOCK_FULL_COLOR:Lerp(BLOCK_EMPTY_COLOR, 0.5)
block.BackgroundTransparency = 0.15
if block:FindFirstChild("Glow") then
block.Glow.ImageColor3 = GLOW_COLOR:Lerp(BLOCK_EMPTY_COLOR, 0.5)
block.Glow.ImageTransparency = GLOW_TRANSPARENCY + 0.2
end
else
block.BackgroundColor3 = BLOCK_EMPTY_COLOR
block.BackgroundTransparency = 0.4
if block:FindFirstChild("Glow") then
block.Glow.ImageColor3 = BLOCK_EMPTY_COLOR
block.Glow.ImageTransparency = 0.7
end
end
end
bar.valueLabel.Text = tostring(math.floor(stamina))
end
-- Play a sound at the player's humanoid root part
local function playSound(soundId, pitch, volume)
local character = LocalPlayer.Character
if not character then return end
local root = character:FindFirstChild("HumanoidRootPart")
if not root then return end
local sound = Instance.new("Sound")
sound.SoundId = soundId
sound.Volume = volume or 0.7
sound.Pitch = pitch or 1
sound.Parent = root
sound.PlayOnRemove = true
sound:Destroy() -- PlayOnRemove triggers sound
end
-- Sprint logic
local function setupSprint(bar)
local character = LocalPlayer.Character or LocalPlayer.CharacterAdded:Wait()
local humanoid = character:FindFirstChildOfClass("Humanoid") or character:WaitForChild("Humanoid")
local stamina = MAX_STAMINA
local isSprinting = false
local runSoundPlaying = false
local baseWalkSpeed = humanoid.WalkSpeed
local exhausted = false
local regenDelay = 0
local lastSprintEnd = 0
-- Helper: Set walk speed
local function setSpeed(speed)
if humanoid.WalkSpeed ~= speed then
humanoid.WalkSpeed = speed
end
end
-- Update baseWalkSpeed if changed externally
humanoid:GetPropertyChangedSignal("WalkSpeed"):Connect(function()
if not isSprinting then
baseWalkSpeed = humanoid.WalkSpeed
end
end)
-- Input handling
local function canSprint()
return stamina > MIN_STAMINA_TO_SPRINT and humanoid.MoveDirection.Magnitude > 0.1 and humanoid.Health > 0 and not exhausted
end
local function startSprint()
if not isSprinting and canSprint() then
isSprinting = true
baseWalkSpeed = humanoid.WalkSpeed
setSpeed(baseWalkSpeed + 20)
if not runSoundPlaying then
playSound(RUN_SOUND_ID, 1, 0.7)
runSoundPlaying = true
end
end
end
local function stopSprint()
if isSprinting then
isSprinting = false
setSpeed(baseWalkSpeed)
runSoundPlaying = false
lastSprintEnd = tick()
regenDelay = exhausted and STAMINA_REGEN_DELAY_EXHAUSTED or STAMINA_REGEN_DELAY
end
end
-- Keyboard input
UserInputService.InputBegan:Connect(function(input, processed)
if processed then return end
if input.KeyCode == Enum.KeyCode.LeftShift or input.KeyCode == Enum.KeyCode.RightShift then
startSprint()
end
end)
UserInputService.InputEnded:Connect(function(input)
if input.KeyCode == Enum.KeyCode.LeftShift or input.KeyCode == Enum.KeyCode.RightShift then
stopSprint()
end
end)
-- Mobile button (optional)
if UserInputService.TouchEnabled then
local sprintBtn = Instance.new("TextButton")
sprintBtn.Name = "SprintButton"
sprintBtn.Text = "SPRINT"
sprintBtn.Size = UDim2.new(0, 70, 0, 24)
sprintBtn.Position = UDim2.new(0, BG_TOTAL_WIDTH + 16, 1, -(BAR_HEIGHT + STAMINA_BAR_MARGIN_Y + 8))
sprintBtn.BackgroundColor3 = BAR_BG_COLOR
sprintBtn.TextColor3 = BAR_TEXT_COLOR
sprintBtn.TextStrokeTransparency = 0.2
sprintBtn.TextStrokeColor3 = BAR_TEXT_STROKE
sprintBtn.Font = Enum.Font.FredokaOne
sprintBtn.TextScaled = true
sprintBtn.Parent = bar.gui
sprintBtn.ZIndex = 10
local btnCorner = Instance.new("UICorner")
btnCorner.CornerRadius = UDim.new(0, 8)
btnCorner.Parent = sprintBtn
sprintBtn.MouseButton1Down:Connect(startSprint)
sprintBtn.MouseButton1Up:Connect(stopSprint)
sprintBtn.TouchEnded:Connect(stopSprint)
end
-- Main update loop
local lastUpdate = tick()
RunService.RenderStepped:Connect(function(dt)
local now = tick()
-- Stamina logic
if isSprinting and canSprint() then
stamina = stamina - STAMINA_DRAIN_RATE * dt
if stamina <= 0 then
stamina = 0
exhausted = true
stopSprint()
regenDelay = STAMINA_REGEN_DELAY_EXHAUSTED
end
elseif not isSprinting then
if regenDelay > 0 then
regenDelay = math.max(0, regenDelay - dt)
else
if exhausted then
stamina = stamina + STAMINA_RECOVER_RATE_EXHAUSTED * dt
if stamina >= MAX_STAMINA * 0.5 then
exhausted = false
end
else
stamina = stamina + STAMINA_RECOVER_RATE * dt
end
if stamina > MAX_STAMINA then stamina = MAX_STAMINA end
end
end
-- If player stops moving, stop sprinting
if isSprinting and humanoid.MoveDirection.Magnitude < 0.1 then
stopSprint()
end
updateStaminaBar(bar, stamina)
end)
-- Reset on respawn
LocalPlayer.CharacterAdded:Connect(function(char)
character = char
humanoid = char:WaitForChild("Humanoid")
stamina = MAX_STAMINA
isSprinting = false
baseWalkSpeed = humanoid.WalkSpeed
setSpeed(baseWalkSpeed)
exhausted = false
regenDelay = 0
updateStaminaBar(bar, stamina)
humanoid:GetPropertyChangedSignal("WalkSpeed"):Connect(function()
if not isSprinting then
baseWalkSpeed = humanoid.WalkSpeed
end
end)
end)
end
-- Main
local staminaBar = createStaminaBar()
setupSprint(staminaBar)
make it that the player can lose all of their stamina (instead of staying at 9 or 10)
make it that if the player runs out of stamina then make them stop running.