JIT
enhancing stamina bar functionality for roblox sprint system
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.
Updated files
v1