I’m making a round-based game that will have a stamina mechanic once the round starts. Right now, it is enabled right when I join the game, and I’m unsure of the best way to disable it.
I have two things in mind that I could do. I could either disable the scripts and enable them once the round starts.
Or I could create a BoolValue for each player, which I can then use to put everything in a condition. Both solutions seem really inefficient.
Another problem is that the stamina is handled by both the client and the server. It is best to put everything in a local script as I heard, but I’m a little worried about it being exploited, and I don’t know how to make anti-exploits yet.
Does anyone have an approach to this? I’m also open to feedback on the code, but it is mostly from a tutorial I followed online.
Client Side
-- [[ Services ]] --
local Players = game:GetService("Players")
local ReplicatedService = game:GetService("ReplicatedStorage")
local UserInputService = game:GetService("UserInputService")
-- [[ Remote Events ]] --
local remoteEvents = ReplicatedService:WaitForChild("RemoteEvents")
local UpdateStamina = remoteEvents:WaitForChild("UpdateStamina")
local Sprint = remoteEvents:WaitForChild("Sprint")
-- [[ Variables ]] --
local localPlayer = Players.LocalPlayer
-- [[ Gui ]] --
local playerGui = localPlayer:WaitForChild("PlayerGui")
local gui = playerGui:WaitForChild("Gui")
local guiObjects = gui:WaitForChild("GuiObjects")
local playerStats = guiObjects:WaitForChild("PlayerStats")
local stamina = playerStats:WaitForChild("Stamina")
local staminaBar = stamina:WaitForChild("StaminaBar")
-- Detects when shift key is pressed
UserInputService.InputBegan:Connect(function(input)
if input.KeyCode == Enum.KeyCode.LeftShift then
Sprint:FireServer("Began")
end
end)
-- Detects when shift key is released
UserInputService.InputEnded:Connect(function(input)
if input.KeyCode == Enum.KeyCode.LeftShift then
Sprint:FireServer("Ended")
end
end)
-- Updates stamina gui locally
UpdateStamina.OnClientEvent:Connect(function(stamina, maxStamina)
staminaBar.Size = UDim2.new((stamina / maxStamina) * 0.2, 0, 0.01, 0)
end)
Server Side
-- [[ Services ]] --
local Players = game:GetService("Players")
local ReplicatedService = game:GetService("ReplicatedStorage")
local RunService = game:GetService("RunService")
-- [[ Remote Events ]] --
local remoteEvents = ReplicatedService:WaitForChild("RemoteEvents")
local UpdateStamina = remoteEvents:WaitForChild("UpdateStamina")
local Sprint = remoteEvents:WaitForChild("Sprint")
-- [[ Variables ]] --
local maxStamina = 100
local staminaRegen = 0.1
local sprintModifier = 1.6
local sprintStaminaCost = 0.4
local sprintingPlayers = {}
Players.PlayerAdded:Connect(function(player)
local stamina = player:WaitForChild("Stamina")
stamina.Value = maxStamina
-- Will update the stamina gui locally
stamina.Changed:Connect(function(property)
UpdateStamina:FireClient(player, stamina.Value, maxStamina)
end)
end)
-- Detects when sprint key is pressed or released
Sprint.OnServerEvent:Connect(function(player, state)
local humanoid = player.Character.Humanoid
-- Checks if the player can sprint
if state == "Began" and humanoid:GetState() == Enum.HumanoidStateType.RunningNoPhysics and humanoid.MoveDirection.Magnitude > 0 then
sprintingPlayers[player.Name] = humanoid.WalkSpeed
humanoid.WalkSpeed = humanoid.WalkSpeed * sprintModifier
elseif state == "Ended" and sprintingPlayers[player.Name] then
humanoid.WalkSpeed = sprintingPlayers[player.Name]
sprintingPlayers[player.Name] = nil
end
end)
-- Updates stamina value
RunService.Heartbeat:Connect(function()
for i,plr in pairs(Players:GetChildren()) do
local stamina = plr.Stamina
local name = plr.Name
-- Changes stamina value when player is not sprinting
if not sprintingPlayers[name] then
if stamina.Value > maxStamina then
stamina.Value = maxStamina
elseif stamina.Value < maxStamina then
stamina.Value = stamina.Value + staminaRegen
end
else
-- Changes stamina value when player is sprinting
if stamina.Value >= sprintStaminaCost then
stamina.Value = stamina.Value - sprintStaminaCost
else
plr.Character.Humanoid.WalkSpeed = sprintingPlayers[name]
sprintingPlayers[name] = nil
end
end
end
end)