Local stamina system not functioning on mobile

I’m using a client sided Stamina system for sprinting and shielding. It works great in studio and on PC/keyboard but on mobile it doesn’t ever regenerate Stamina.

Does anyone have any ideas as to why? The only SERVER side function is giving the player the shield in exchange for a full stamina bar but the stamina reset is still done by the client. The fact that it works on CPU makes me think there’s an issue with either the input service while using mobile but I have no idea what’s wrong.

This is in starter player to create the local stamina value.

local players = game:GetService("Players")
local player = players.LocalPlayer

local function onCharacterSpawn()
	print ("giving stamina")
	local stamina = Instance.new("IntValue", player)
	stamina.Value = 500 			--player:WaitForChild("PlayerInfo"):WaitForChild("MaxStamina")
	stamina.Name = "Stamina"
	stamina.Parent = player
end

player.CharacterAdded:Connect(onCharacterSpawn)

Here’s the sprint / stamina regen script: It’s currently a local script in starter character. I’ve tried using it in starter player as well but then it stops working after the player dies. I know my waits are probably over the top or unnecessary but I have a hard time not getting random timeouts with my scripts.

local UserInputService = game:GetService("UserInputService")
local replicatedStorage = game:GetService("ReplicatedStorage")
local players = game:GetService("Players")
local RunService = game:GetService("RunService")

repeat wait() until game.Players.LocalPlayer and game.Players.LocalPlayer.Character
local player = players.LocalPlayer
repeat wait() until player:WaitForChild("PlayerGui")~=nil
repeat wait() until player:WaitForChild("Stamina")~=nil

local MaxStamina = player.PlayerInfo.MaxStamina
local PlayerGui = player:WaitForChild("PlayerGui")
local gui = PlayerGui.BasicGui.StaminaGui
local sprintButton = gui.Frame.SprintButton
local sprintLabel = gui.Frame.SprintLabel



local function setButton()


local touchGui = PlayerGui:FindFirstChild("TouchGui")
	
	
	if touchGui == nil then 
		--no button for sprint just shift text label
		sprintButton.Visible = false 
		sprintLabel.Visible = true
		
	else --button to sprint must be enabled
		
		sprintButton.Visible = true
		sprintLabel.Visible = false
	
	end
end




local SprintHeld = false
local Sprinting = false
local Exhausted = false
local RunRefresh = 200 -- when to allow running after exhausted
local SpeedDiff = 20
local DrainRate = 100 -- drain per second

local function sprint(active) --Fixed by redfining humanoid locally, as humanoids need to be refreshed on respawn
	local Stamina = player.Stamina
	local newHumanoid = player.Character:WaitForChild("Humanoid")
	
	if Exhausted then return end -- we can't run because we're exhausted!
	if active then
		newHumanoid.WalkSpeed = newHumanoid.WalkSpeed + SpeedDiff
	else
		newHumanoid.WalkSpeed = newHumanoid.WalkSpeed - SpeedDiff
	end
	Sprinting = active
end

--defining shift input OR button click/release

UserInputService.InputBegan:Connect(function(input)
	if input.KeyCode ~= Enum.KeyCode.LeftShift then return end
	SprintHeld = true
	sprint(SprintHeld)
end)

UserInputService.InputEnded:Connect(function(input)
	if input.KeyCode ~= Enum.KeyCode.LeftShift then return end
	SprintHeld = false
	sprint(SprintHeld)
end)


sprintButton.MouseButton1Down:Connect(function() SprintHeld = true sprint(SprintHeld) end)
sprintButton.MouseButton1Up :Connect(function() SprintHeld = false sprint(SprintHeld) end)


--Sprint functionality and Stamina regen

RunService.Heartbeat:Connect(function(DeltaTime)
	local Stamina = player.Stamina
	if Sprinting then
		if Stamina.Value > 0 then
			Stamina.Value = Stamina.Value - DrainRate * DeltaTime
		else
			sprint(false)
			Exhausted = true
		end
	elseif Stamina.Value < MaxStamina.Value then
		Stamina.Value = Stamina.Value + (DrainRate*.25 * DeltaTime)
		if Stamina.Value > RunRefresh then -- we can now run again!
			Exhausted = false
			if SprintHeld then -- resume running because player is still holding down the sprint key!
				sprint(SprintHeld)
			end
		end
	end
end)

setButton()


players.PlayerAdded:Connect(setButton)

player.CharacterAdded:Connect(function()wait(3) setButton() end)

Finally the local shield script in playerGui

local debris = game:GetService("Debris")
local replicatedStorage = game:GetService("ReplicatedStorage")
local players = game:GetService("Players")


repeat wait() until game.Players.LocalPlayer and game.Players.LocalPlayer.Character
local player = players.LocalPlayer
local Humanoid = player.Character.Humanoid

local playerInfo = player:WaitForChild("PlayerInfo")
local MaxStamina = playerInfo:WaitForChild("MaxStamina")
local Stamina = player:WaitForChild("Stamina")

--if Humanoid ~= nil then print ("humanoid found in shield script")end
--print (player.Name.." found in shield script")


	
local function shield()
	--print(player.Name.. " Getting Shield")
	
	if Stamina.Value >= (MaxStamina.Value-5) then 
		Stamina.Value = 0
		
		
		game.ReplicatedStorage.Events.Shield:FireServer(player)
		
		
	end
end		


script.Parent.MouseButton1Click:Connect(shield)

-------------------------------------keyboard special input
local UserInputService = game:GetService("UserInputService")

UserInputService.InputEnded:Connect(function(input)
	if input.KeyCode ~= Enum.KeyCode.E then return end
	shield()

end)

That’s all the code except the server sided event script to add and remove the shield from the player when the event fires.

Thanks for any help!

Not quite sure but you’ll have to detect input from by a player that is on the mobile as well.
Right now you’re just using InputEnded and InputBegan, may you try to use some sort of mobile input listeners

1 Like

There’s buttons for the mobile to click. SprintButton Button1up and 1 down connect to the function. They’re right after the key input listeners. They work correctly but the stamina just doesn’t recharge for mobile.

I switched some settings around and rigged my stamina value to a numerical stat display, it turns out that it very very slowly recharges on mobile but it quits recharging after a short while. Now I think the problem lies somewhere in my lack of knowledge on run service and heartbeat especially how it pertains to mobile. At least it’s a direction to start learning about for the time being. Sad my game has been busted for a few days but I’ll get there…

Alright, when I adjust the line

Stamina.Value = Stamina.Value + (DrainRate * DeltaTime) by removing the extra *.25 (to slow the recharge) it started functioning correctly. I’ll try defining the recharge rate to a smaller value as the *.25 seems to be causing the issue. My understanding of DeltaTime must have been the issue I wasn’t thinking it could consider it differently when multiplying by a fraction and another variable. An extra set of parentheses between the drainrate and .25 would probably fix it but for now it is bed time.

Im not sure why but when I lower the recharge rate below approximately 30 (100 is how fast stamina rate drains) the stamina no longer recharges on mobile. I may have to introduce some new bool values to slow the recharge system but I’ll probably try to figure out why that is even necessary on mobile while pc is capable of supporting the lower regeneration rate multiplied by DeltaTime.