To provide some context, I created this sprint system a few years ago when I was a beginner, and I’m now updating it to an improved version for you to enjoy!
For now, this resource include camera effects, GUI, and a stamina system.
Let me know if you would be interested in a more advanced version that could include footstep particles, custom character sounds and animations, improved camera effects, and more.
📌 Update Note 📌
22th February 2025
The overall code has been slightly optimized and improved.
Some minor issues have been fixed.
The scripts have been moved to StarterPlayerScripts.
The system is now modular.
A cooldown has been added before stamina regeneration starts.
WalkSpeed now changes using TweenService for a smoother transition.
Mouse lock is now automatically set to LeftControl whenever your sprint keybind is LeftShift.
The sprint no longer continue when your character is not moving.
Yep that’s right, but making it in server is going to take too much ressources for the server and decrease game performances.
So you need to choose between a exploitable system or a laggy game.
you might want to explain what the code do, so when a beginner look at your codeblock they roughly understand the concept of it rather than copy and paste and not learning anything.
The value inside the script is a bool, to check sprint activation, so don’t care if exploiter are changing it, it will just active or desactive the sprint.
You still can store the “MaxStamina” and “Stamina” as player values in server side , then add a RemoteEvent:FireServer() inside the “Sprinting()” and “Regen” functions (do the repeat code inside the server side script with “onserverevent”) and run the BarResize with Stamina.Changed so the most important stats can’t be exploited.
local function Sprinting()
RemoteEvent:FireServer()
end
local function Regen()
RemoteEvent:FireServer()
end
local function BarResize()
FrameGoal.Size = UDim2.fromScale(Stamina / MaxStamina, 1)
FrameTween = TweenService:Create(script.Parent.Bar.Frame, Infos, FrameGoal)
FrameTween:Play()
script.Parent.Bar.Info.Text = Stamina.. "/" ..MaxStamina
end
Player.Stamina.Changed:Connect(function()
BarResize()
end)
I had to edit it a little bit to put this on my game, I added Regen CoolTime, Regen Increasement, Stamina Decreasement per .1 second to settings. I’ll leave it below but I’m kinda new to scripting so you may expect some issues.
-- Unofficial Sprinting System Update --
-- By: @qazxqwer21
-- Original(@Crygen54): https://devforum.roblox.com/t/updated-sprinting-system-stamina-gui-bar-camera-change/1215024
-- Added Regen CoolTime, Regen Increasement, Stamina Usage to settings
local UserInputService = game:GetService("UserInputService")
local TweenService = game:GetService("TweenService")
local PlayersStorage = game:GetService("Players")
local WorkspaceStorage = game:GetService("Workspace")
--// Variables //--
local Player = PlayersStorage.LocalPlayer
local Character = Player.Character
local Camera = WorkspaceStorage.CurrentCamera
local Humanoid = Character:WaitForChild("Humanoid" ,10)
local Infos = TweenInfo.new(0.25)
local FrameGoal = {}
local CameraGoal = {}
local FrameTween = {}
local CameraTween = {}
--// Settings //--
local CameraChangeEnabled = true
local Keybind = "LeftShift"
local MaxStamina = 100
local NormalWalkspeed = 16
local SprintWalkspeed = 25
local NormalCameraFOV = 70
local SprintCameraFOV = 80
local RegenCoolTime = 1
local RegenIncreasement = 2
local Decreasement = 1 --Stamina Usage per .1 second
--// Values //--
local Stamina = MaxStamina
local State = false
local Debounce = false
local WaitingTime = 0
--// Functions //--
local function BarResize()
FrameGoal.Size = UDim2.fromScale(Stamina / MaxStamina, 1)
FrameTween = TweenService:Create(script.Parent.Bar.Frame, Infos, FrameGoal)
FrameTween:Play()
script.Parent.Bar.Info.Text = Stamina.. "/" ..MaxStamina
end
local function Sprinting()
if State == true and Humanoid and Stamina > 0 then
Humanoid.WalkSpeed = SprintWalkspeed
repeat
wait(0.1)
Stamina -= Decreasement
BarResize()
until
Stamina <= 0 or State == false
if Stamina <= 0 then
Stamina = 0
BarResize()
end
Humanoid.WalkSpeed = NormalWalkspeed
end
end
local function Regen()
if State == false and Stamina < MaxStamina then
repeat
wait(0.1)
Stamina += RegenIncreasement
BarResize()
until
Stamina >= MaxStamina or State == true
if Stamina >= MaxStamina then
Stamina = MaxStamina
BarResize()
end
end
end
local function CameraChange()
if State == true and CameraChangeEnabled == true then
CameraGoal.FieldOfView = SprintCameraFOV
CameraTween = TweenService:Create(Camera, Infos, CameraGoal)
CameraTween:Play()
elseif State == false and CameraChangeEnabled == true then
CameraGoal.FieldOfView = NormalCameraFOV
CameraTween = TweenService:Create(Camera, Infos, CameraGoal)
CameraTween:Play()
end
end
--// Connections //--
UserInputService.InputBegan:Connect(function(key, processed)
if key.UserInputType == Enum.UserInputType.Keyboard then
if key.KeyCode == Enum.KeyCode[Keybind] then
State = true
CameraChange()
Sprinting()
end
end
end)
UserInputService.InputEnded:Connect(function(key, processed)
if key.UserInputType == Enum.UserInputType.Keyboard then
if key.KeyCode == Enum.KeyCode[Keybind] then
State = false
CameraChange()
if Debounce == false then
Debounce = true
while not State do
task.wait(.1)
WaitingTime += 0.1
if WaitingTime > RegenCoolTime then
WaitingTime = 0
Regen()
break
end
end
Debounce = false
end
end
end
end)
You could have asked me for an update.
This resource was years old, so as you are expecting an improvement, I’ve created a new version. You can look back at the main post.
Feel free to provide feedback and suggestions, as well as reporting bugs if you find some.