As the title suggests, I am trying to create a sprint system that considers mobile devices (in addition to computers).
I have based the system on my original sprinting mechanic, which involves stamina loss and an exhaustion state (used UserInputService), but the script I have does not work (ContextActionService). There is no error in the output, and I am also at a loss for what to do.
Script:
local Player = game.Players.LocalPlayer
local Character = Player.Character
local Humanoid = Character:FindFirstChildOfClass("Humanoid")
local ContextActionService = game:GetService("ContextActionService")
local Stamina = 100
local RunRefresh = 20 -- minimum level to allow sprinting after exhausted
local Running = false
local Exhausted = false
local function Sprinting(Action, GPE, InputState)
if Action == "Sprinting" and InputState == Enum.UserInputState.Begin and not GPE then
if Exhausted then return end
Running = true
Humanoid.WalkSpeed = 28
while Running do
if Stamina > 0 then
Stamina -= 0.25
script.Parent:TweenSize(UDim2.new(Stamina / 100, 0, 1, 0), "Out", "Linear", 0)
else
Exhausted = true
Humanoid.WalkSpeed = 16
break
end
task.wait() -- delay between stamina loss
end
elseif Action == "Sprinting" and InputState == Enum.UserInputState.End and not GPE then
Running = false
Humanoid.WalkSpeed = 16
end
end
task.spawn(function() -- task.spawn used to not yield code
while true do
if Stamina < 100 and not Running then -- 46 seconds until Stamina = 100
Stamina += 0.075
script.Parent:TweenSize(UDim2.new(Stamina / 100, 0, 1, 0), "Out", "Linear", 0)
task.wait() -- delay between stamina gain
Exhaustion()
end
task.wait()
end
end)
function Exhaustion()
if Stamina > RunRefresh then -- we can now run again!
Exhausted = false
end
end
ContextActionService:BindAction("Sprinting", Sprinting, true, Enum.KeyCode.LeftShift)
The script used the wrong service to detect keyboard input. Instead of using ContextActionService, it should use UserInputService.
The conditions for checking the input state were incorrect in the original script. They have been fixed in the modified script to correctly handle the start and end of the key press.
The Exhaustion function was placed in the wrong location in the original script, causing it to be called multiple times per frame. It has been moved to the correct location so that it is called once per frame.
local Player = game.Players.LocalPlayer
local Character = Player.Character
local Humanoid = Character:FindFirstChildOfClass("Humanoid")
local UserInputService = game:GetService("UserInputService")
local Stamina = 100
local RunRefresh = 20 -- minimum level to allow sprinting after exhausted
local Running = false
local Exhausted = false
local function Sprinting(Action, InputState)
if Action == "Sprinting" and InputState == Enum.UserInputState.Begin then
if Exhausted then return end
Running = true
Humanoid.WalkSpeed = 28
while Running do
if Stamina > 0 then
Stamina -= 0.25
script.Parent:TweenSize(UDim2.new(Stamina / 100, 0, 1, 0), "Out", "Linear", 0)
else
Exhausted = true
Humanoid.WalkSpeed = 16
break
end
task.wait() -- delay between stamina loss
end
elseif Action == "Sprinting" and InputState == Enum.UserInputState.End then
Running = false
Humanoid.WalkSpeed = 16
end
end
task.spawn(function()
while true do
if Stamina < 100 and not Running then -- 46 seconds until Stamina = 100
Stamina += 0.075
script.Parent:TweenSize(UDim2.new(Stamina / 100, 0, 1, 0), "Out", "Linear", 0)
end
Exhaustion()
task.wait()
end
end)
function Exhaustion()
if Stamina > RunRefresh then -- we can now run again!
Exhausted = false
end
end
UserInputService.InputBegan:Connect(function(input, processed)
if not processed and input.KeyCode == Enum.KeyCode.LeftShift then
Sprinting("Sprinting", Enum.UserInputState.Begin)
end
end)
UserInputService.InputEnded:Connect(function(input, processed)
if not processed and input.KeyCode == Enum.KeyCode.LeftShift then
Sprinting("Sprinting", Enum.UserInputState.End)
end
end)
The modified script now includes input event handlers (InputBegan and InputEnded) that accurately detect the LeftShift key press and release. These event handlers trigger the sprinting action accordingly.
I apologise for the late reply, but there are some errors presented in the output that I will relay to you:
task.spawn(function()
while true do
if Stamina < 100 and not Running then -- 46 seconds until Stamina = 100
Stamina += 0.075
script.Parent:TweenSize(UDim2.new(Stamina / 100, 0, 1, 0), "Out", "Linear", 0)
end
Exhaustion() -- upon spawn, the player is received an error here: attempt to call a nil value
task.wait()
end
end)
The next issues may be a consequence of the problem above, but I figure it is important to convey them, too!
local function Sprinting(Action, InputState)
if Action == "Sprinting" and InputState == Enum.UserInputState.Begin then
if Exhausted then return end
Running = true
Humanoid.WalkSpeed = 28 -- When the Player begins Sprinting: attempt to index nil with 'WalkSpeed'
while Running do
if Stamina > 0 then
Stamina -= 0.25
script.Parent:TweenSize(UDim2.new(Stamina / 100, 0, 1, 0), "Out", "Linear", 0)
else
Exhausted = true
Humanoid.WalkSpeed = 16 -- When the Player stops Sprinting: attempt to index nil with 'WalkSpeed'
break
end
task.wait()
end
elseif Action == "Sprinting" and InputState == Enum.UserInputState.End then
Running = false
Humanoid.WalkSpeed = 16
end
end
Make sure that you are accessing the correct humanoid object. Instead of using Character:FindFirstChildOfClass("Humanoid"), you can directly access it using Character.Humanoid. Update the following line:
local Humanoid = Character:FindFirstChildOfClass("Humanoid")
to:
local Humanoid = Character.Humanoid
Additionally, ensure that the Character object is not nil. You can add a check to make sure that the Character object exists before accessing the Humanoid property. Modify the line:
local Character = Player.Character
to:
local Character = Player.Character or Player.CharacterAdded:Wait()
Just got an issue: the player’s stamina does not regenerate, and I am receiving an error in a block, which I have attached below:
task.spawn(function()
while true do
if Stamina < 100 and not Running then
Stamina += 0.075
script.Parent:TweenSize(UDim2.new(Stamina / 100, 0, 1, 0), "Out", "Linear", 0)
end
ExhaustionRecovery() -- attempt to call a nil value
task.wait()
end
end)
function ExhaustionRecovery() -- Changed function name for clarity
if Stamina > RunRefresh then
Exhausted = false
end
end
This is displayed in the output as soon as the player joins.
Ok, well because of some complications with the stamina system, it is entirely possible I sent in a dysfunctional script as I attempted to create one using ContextActionService in my original post.
Therefore, I will send in my original sprinting mechanic. How would I turn this sprinting system to be compatible with mobile devices?
local Player = game.Players.LocalPlayer
local Character = Player.Character
local UserInputService = game:GetService("UserInputService")
local Stamina = 100
local RunRefresh = 20 -- when to allow running after exhausted
local Running = false
local Exhausted = false
UserInputService.InputBegan:Connect(function(Input, gPE)
if Player.Team.Name == "Agents" then -- Did not mention in my original post as it is not necessary, but I will add it for extra context
if (Input.KeyCode == Enum.KeyCode.LeftShift) and not gPE then
if Exhausted then return end
Running = true
Player.Character.Humanoid.WalkSpeed = 32
while Running do
if Stamina > 0 then
Stamina -= 0.25
script.Parent:TweenSize(UDim2.new(Stamina / 100, 0, 1, 0), "Out", "Linear", 0)
else
Exhausted = true
Player.Character.Humanoid.WalkSpeed = 16
break
end
task.wait()
end
end
end
end)
UserInputService.InputEnded:Connect(function(Input, gPE)
if (Input.KeyCode == Enum.KeyCode.LeftShift) and not gPE then
Running = false
Player.Character.Humanoid.WalkSpeed = 16
end
end)
task.spawn(function() -- Not yield code
while true do
if Stamina < 100 and not Running then
Stamina += 0.075
script.Parent:TweenSize(UDim2.new(Stamina / 100, 0, 1, 0), "Out", "Linear", 0)
task.wait() -- Delay between stamina gain
Exhaustion()
end
task.wait()
end
end)
function Exhaustion()
if Stamina > RunRefresh then -- Player may run again
Exhausted = false
end
end
local function Sprint(_, state)
if state == Enum.UserInputState.Begin then
if Player.Team.Name == "Agents" then
if Exhausted then return end
Running = true
Player.Character.Humanoid.WalkSpeed = 32
while Running do
if Stamina > 0 then
Stamina -= 0.25
script.Parent:TweenSize(UDim2.new(Stamina / 100, 0, 1, 0), "Out", "Linear", 0)
else
Exhausted = true
Player.Character.Humanoid.WalkSpeed = 16
break
end
task.wait()
end
end
elseif state == Enum.UserInputState.End then
Running = false
Player.Character.Humanoid.WalkSpeed = 16
end
end
ContextActionService:BindAction("Sprint", Sprint, true, Enum.KeyCode.LeftShift)
ContextActionService:SetPosition("Sprint", UDim2.new(0.9, 0, 0.8, 0))
ContextActionService:SetTitle("Sprint")
I am getting this error message with the last line:
ContextActionService:SetTitle(Sprint) -- Argument 2 missing or nil
Reviewing the page for ContextActionService, it seems to be missing some designated text for the ui button, but when I change it (e.g., Sprint, "Sprint"), I receive this error message:
ContextActionService could not find the function passed in, doing nothing.