Making a combat game with sprinting and blocking, but have run into quite a few issues
Sprinting
1 - The sprint animation will not stop after the player runs out of stamina (same for block)
2 - The run triggers when holding the shift even if I’m not moving anywhere
3 - (When using humanoid.MoveDirection.Magnitude as a fix) When I walk first and hold shift afterwards, it works fine. But if I hold shift and then walk afterwards, nothing fires. No animation or stamina depletion
4 - When I let go of any WASD while sprinting, the sprinting is still functioning
Other
When holding any key, I’m able to trigger other actions, such as the sprint while blocking, block while sprinting, melee, etc. The other keys arent blocked out
NOTES:
-All of these issues are mainly with the local script/animation. The server only continues firing for issue #4
-I handle the animations on the client because I assume it should handle faster than the server for most things. I handle the stamina and other values on the server so the client cant exploit them obviously
-Ive read that it may be better to handle animations outside of UserInputService?
-The animations are loops
-Tried using humanoid.MoveDirection.Magnitude > 0 in some ways, only managed to fix issue #2
Here is a snippet of my code:
Local Script
local player = game.Players.LocalPlayer
local character = player.Character or player.CharacterAdded:Wait()
local humanoid = character:WaitForChild("Humanoid")
---Attempt to handle things outside of UserInputService. Was off in the video
local isMoving = false
humanoid:GetPropertyChangedSignal("MoveDirection"):Connect(function()
if humanoid.MoveDirection.Magnitude > 0 and UserInputService:IsKeyDown(Enum.KeyCode.E) then
PlayAnimation(Anim, true, 1.8)
isMoving = true
elseif humanoid.MoveDirection.Magnitude < 0 then
Anim:Stop()
isMoving = false
end
end)
---input
UserInputService.InputBegan:Connect(function(input, isTyping)
if isTyping then return end
if input.KeyCode == Enum.KeyCode.R then ---block
if player.Stamina.Value >= 3 then
local Animation = humanoid:LoadAnimation(game.ReplicatedStorage.BlockAnim)
Animation:Play()
humanoid.WalkSpeed = 3
DefaultEvent:FireServer("Block")
end
elseif input.KeyCode == Enum.KeyCode.LeftShift then -- sprint
if player.Stamina.Value >= 3 and humanoid.MoveDirection.Magnitude > 0 then
local Animation = humanoid:LoadAnimation(game.ReplicatedStorage.SprintAnim)
Animation:Play()
DefaultEvent:FireServer("Run")
end
end
end)
UserInputService.InputEnded:Connect(function(input, isTyping)
if isTyping then return end
if input.KeyCode == Enum.KeyCode.R then
DefaultEvent:FireServer("BlockEnd")
humanoid.WalkSpeed = 16
local playingAnimations = humanoid:GetPlayingAnimationTracks()
for i, v in pairs (playingAnimations) do
if v.Name == BlockAnim.Name then v:Stop() end
end
elseif input.KeyCode == Enum.KeyCode.LeftShift then
DefaultEvent:FireServer("RunEnd")
humanoid.WalkSpeed = 16
local playingAnimations = humanoid:GetPlayingAnimationTracks()
for i, v in pairs (playingAnimations) do
if v.Name == SprintAnim.Name then v:Stop() end
end
end
end)
Server Script
game.Players.PlayerAdded:Connect(function(player)
local Stamina = Instance.new("IntValue", player)
Stamina.Value = 300
Stamina.Name = "Stamina"
end)
----Receiving event from Local Script and detecting which action
local DefaultEvent = game.ReplicatedStorage.DefaultEvent
DefaultEvent.OnServerEvent:Connect(function(player, Action)
local character = player.Character or player.CharacterAdded:Wait()
local humanoid = character:FindFirstChild("Humanoid")
if playerTable[player.UserId] == nil then
playerTable[player.UserId] = {
Blocking = false,
Running = false,
UsingStamina = false,
WalkSpeed = humanoid.WalkSpeed
}
end
local playerKey = playerTable[player.UserId]
humanoid.WalkSpeed = playerKey.WalkSpeed
if Action == "Block" then
playerKey.Blocking = true
playerKey.UsingStamina = true
elseif Action == "BlockEnd" then
playerKey.Blocking = false
playerKey.UsingStamina = false
humanoid.WalkSpeed = playerKey.WalkSpeed
elseif Action == "Run" then
playerKey.Running = true
playerKey.UsingStamina = true
elseif Action == "RunEnd" then
playerKey.Running = false
playerKey.UsingStamina = false
humanoid.WalkSpeed = playerKey.WalkSpeed
end
end)
---- Changing the stamina value
Run.Heartbeat:Connect(function()
for i, v in pairs(game.Players:GetChildren()) do
if playerTable[v.UserId] then
local playerKey = playerTable[v.UserId]
local player = v
local character = v.Character
local humanoid = v.Humanoid
local Stamina = v.Stamina or v.Backpack.Stamina
if playerKey.Blocking and Stamina.Value > 5 then ---block
Stamina.Value -= 2
humanoid.WalkSpeed = 3
if Stamina.Value < 0 then
Stamina.Value = 0
playerKey.Blocking = false
humanoid.WalkSpeed = playerKey.WalkSpeed
end
elseif playerKey.Running and Stamina.Value >= 2 then ---run
Stamina.Value -= 2
humanoid.WalkSpeed = 30
if Stamina.Value < 0 then
Stamina.Value = 0
playerKey.Running = false
humanoid.WalkSpeed = playerKey.WalkSpeed
end
end
end
end
end)
There were a few other things I tried but I don’t want to make this post more convoluted. Really sad that there have been so many issues. Grateful for any help!