This should be relatively simple for other people but I just can’t figure out how to my this run script toggleable with the shift key. Currently its just if you hold it you sprint and when you let go you stop. I want it to be you sprint by clicking the key and stop by clicking it again. If you could help it would mean a lot.
local userInputService = game:GetService("UserInputService")
local players = game:GetService("Players")
local player = players.LocalPlayer
local char = player.Character or player.CharacterAdded:Wait()
local hum = char:WaitForChild("Humanoid")
local animator = hum:WaitForChild("Animator")
local animation = Instance.new("Animation")
animation.AnimationId = "rbxassetid://15720702879"
local track = animator:LoadAnimation(animation)
track.Priority = Enum.AnimationPriority.Movement
local running = false
local RUN_KEYCODE = Enum.KeyCode.LeftShift
local RUN_SPEED = 35
local WALK_SPEED = 16
local function run(runBool) -- So we don't have to repeat the same commands
if runBool then
if hum.MoveDirection.Magnitude <= 0 then return end -- If not moving then stop function execution
hum.WalkSpeed = RUN_SPEED
track:Play()
else
hum.WalkSpeed = WALK_SPEED
track:Stop()
end
running = runBool
end
local function inputBegan(input, processed)
if processed then return end
if input.KeyCode == RUN_KEYCODE then
run(true)
end
end
local function inputEnded(input, processed)
if processed then return end
if input.KeyCode == RUN_KEYCODE then
run(false)
end
end
local function moveDirectionChanged()
local magnitude = hum.MoveDirection.Magnitude
if magnitude <= 0 then
if running then
run(false)
end
end
end
userInputService.InputBegan:Connect(inputBegan)
userInputService.InputEnded:Connect(inputEnded)
hum:GetPropertyChangedSignal("MoveDirection"):Connect(moveDirectionChanged)
Having a function that updates the character might get confusing, especially when dealing with sprinting (and having a check to check if your character isn’t moving, which a lot of games fail to do!). I would suggest using global variables to manage the states of your inputs, and using RunService to constantly check the inputs in order to play/stop animations and set the WalkSpeed as necessary!
I also want to note that the gameProcessed check in each of your inputBegan and inputEnded (more specifically for inputBegan) might return true if the player has shift lock enabled, so I disabled that check for now.
I assume this is placed in StarterCharacterScripts?
local userInputService = game:GetService("UserInputService")
local players = game:GetService("Players")
local RunService = game:GetService("RunService")
local player = players.LocalPlayer
local char = player.Character or player.CharacterAdded:Wait()
local hum = char:WaitForChild("Humanoid")
local animator = hum:WaitForChild("Animator")
local animation = Instance.new("Animation")
animation.AnimationId = "rbxassetid://15720702879"
local track = animator:LoadAnimation(animation)
track.Priority = Enum.AnimationPriority.Movement
local RUN_KEYCODE = Enum.KeyCode.LeftShift
local RUN_SPEED = 35
local WALK_SPEED = 16
local running = false
local key_down = false
local is_playing_animation = false
-- Plays running animation
local function playAnimation()
if is_playing_animation then
return
end
is_playing_animation = true
track:Play()
end
-- Stops running animation
local function stopAnimation()
if not is_playing_animation then
return
end
is_playing_animation = false
track:Stop()
end
local function run(runBool)
if runBool then
hum.WalkSpeed = RUN_SPEED
playAnimation()
print("RUNNING")
else
hum.WalkSpeed = WALK_SPEED
stopAnimation()
print("NOT RUNNING")
end
end
-- Create a checker
local checker: RBXScriptConnection
checker = RunService.Heartbeat:Connect(function()
-- If player gets respawned or dies, stop the checker
if not char.Parent or hum.Health == 0 then
checker:Disconnect()
return
end
-- Update running states
if running then
if hum.MoveDirection.Magnitude > 0 then
run(true)
else
run(false)
end
else
run(false)
end
end)
local function inputBegan(input, processed)
--if processed then return end
if input.KeyCode == RUN_KEYCODE then
print("BEGAN")
running = true
end
end
local function inputEnded(input, processed)
--if processed then return end
if input.KeyCode == RUN_KEYCODE then
print("ENDED")
running = false
end
end
local function moveDirectionChanged()
local magnitude = hum.MoveDirection.Magnitude
if magnitude <= 0 then
running = false
end
end
userInputService.InputBegan:Connect(inputBegan)
userInputService.InputEnded:Connect(inputEnded)
hum:GetPropertyChangedSignal("MoveDirection"):Connect(moveDirectionChanged)
I added print statement for debugging, feel free to remove them once you’re comfortable with how this works!
I changed your code a little to do this. Instead of passing a boolean as a function parameter into your run function, I instead store it in a global variable right above the function.
I also removed the InputEnded function, and instead added an if check inside the InputBegan.
Im not entirely sure what the moveDirectionChanged function is for, so I just left it untouched. Hence why there is your running variable, and my runBool variable. Hope this helps!
local userInputService = game:GetService("UserInputService")
local players = game:GetService("Players")
local player = players.LocalPlayer
local char = player.Character or player.CharacterAdded:Wait()
local hum = char:WaitForChild("Humanoid")
local animator = hum:WaitForChild("Animator")
local animation = Instance.new("Animation")
animation.AnimationId = "rbxassetid://15720702879"
local track = animator:LoadAnimation(animation)
track.Priority = Enum.AnimationPriority.Movement
local running = false
local RUN_KEYCODE = Enum.KeyCode.LeftShift
local RUN_SPEED = 100
local WALK_SPEED = 16
local runBool = false
local function run() -- So we don't have to repeat the same commands
if runBool then
if hum.MoveDirection.Magnitude <= 0 then return end -- If not moving then stop function execution
hum.WalkSpeed = RUN_SPEED
track:Play()
else
hum.WalkSpeed = WALK_SPEED
track:Stop()
end
end
local function inputBegan(input, processed)
if processed then return end
if input.KeyCode == RUN_KEYCODE then
if runBool then runBool = false
else runBool = true end
run()
end
end
local function moveDirectionChanged()
local magnitude = hum.MoveDirection.Magnitude
if magnitude <= 0 then
if running then
run(false)
end
end
end
userInputService.InputBegan:Connect(inputBegan)
hum:GetPropertyChangedSignal("MoveDirection"):Connect(moveDirectionChanged)