After a week of struggling, I managed to implement walking and jogging, and I’m now struggling with running.
Detecting if the player has pressed a key in a specific time window, and only calling the StartRunning() from the DefaultMovement module script (which handles WalkSpeed changes) when that key is pressed under the time window works — except when “that key” is W. I have no idea why, and I don’t even know how do I even begin on trying to figure this out.
Here follows the script.
-- InputHandler
local Players = game:GetService("Players");
local UserInputService = game:GetService("UserInputService");
local player = Players.LocalPlayer;
local character = player.Character or player.CharacterAdded:Wait();
local humanoid = character:WaitForChild("Humanoid");
local DefaultMovement = require(script.DefaultMovement);
local isWalking = false;
local isJogging = false;
local currentTick = 0;
local lastTick = currentTick;
local tickWindow = 0.8;
UserInputService.InputBegan:Connect(function(input)
if isWalking == false and input.KeyCode == Enum.KeyCode.W then
isWalking = true;
warn("Is " .. player.Name .. " walking?");
DefaultMovement.StartWalking();
--
elseif input.KeyCode == Enum.KeyCode.LeftShift then
isWalking = false;
isJogging = true;
warn("Is " .. player.Name .. " jogging?");
DefaultMovement.StopWalking();
DefaultMovement.StartJogging();
--
elseif input.KeyCode == Enum.KeyCode.F and tick() - lastTick <= tickWindow then
-- Tried replacing the W key with any other and it worked
-- Does not work exclusively with W and I have no idea why
warn("Is " .. player.Name .. " running?");
DefaultMovement.StartRunning();
end
end)
UserInputService.InputEnded:Connect(function(input)
if isWalking and input.KeyCode == Enum.KeyCode.W then
isWalking = false;
warn(player.Name .. " will stop walking.");
DefaultMovement.StopWalking();
lastTick = tick();
elseif not isWalking and input.KeyCode == Enum.KeyCode.LeftShift then
isWalking = true;
isJogging = false;
warn("——" .. player.Name .. " will stop jogging.");
DefaultMovement.StopJogging();
elseif not isJogging and input.KeyCode == Enum.KeyCode.F then
warn("——" .. player.Name .. " will stop running.");
DefaultMovement.StopRunning();
end
end)
I’m sure there is a better way going about this, but I’m just gonna tell you what’s happening.
The line: if isWalking == false and input.KeyCode == Enum.KeyCode.W then is being triggerd every time because when you release “W” this line if isWalking and input.KeyCode == Enum.KeyCode.W then activates. So they go back and forth, which is why you never make it to elseif input.KeyCode == Enum.KeyCode.F and tick() - lastTick <= tickWindow then with a “W” key. So it goes, isWalking = true then isWalking = fasle reapeatedly, no matter how fast you press the keys, and only one if statement can be triggered so…
Basically I just changed some stuff around:
local Players = game:GetService("Players");
local UserInputService = game:GetService("UserInputService");
local player = Players.LocalPlayer;
local character = player.Character or player.CharacterAdded:Wait();
local humanoid = character:WaitForChild("Humanoid");
--local DefaultMovement = require(script.DefaultMovement);
local isWalking = false;
local isJogging = false;
local currentTick = 0;
local lastTick = currentTick;
local tickWindow = 0.8;
UserInputService.InputBegan:Connect(function(input)
if input.KeyCode == Enum.KeyCode.W and tick() - lastTick <= tickWindow then
-- Tried replacing the W key with any other and it worked
-- Does not work exclusively with W and I have no idea why
warn("Is " .. player.Name .. " running?");
--DefaultMovement.StartRunning();
elseif isWalking == false and input.KeyCode == Enum.KeyCode.W then
isWalking = true;
warn("Is " .. player.Name .. " walking?");
--DefaultMovement.StartWalking();
--
lastTick = tick();
elseif input.KeyCode == Enum.KeyCode.LeftShift then
isWalking = false;
isJogging = true;
warn("Is " .. player.Name .. " jogging?");
--DefaultMovement.StopWalking();
--DefaultMovement.StartJogging();
--
end
end)
UserInputService.InputEnded:Connect(function(input)
if isWalking and input.KeyCode == Enum.KeyCode.W then
isWalking = false;
warn(player.Name .. " will stop walking.");
--DefaultMovement.StopWalking();
--lastTick = tick();
elseif not isWalking and input.KeyCode == Enum.KeyCode.LeftShift then
isWalking = true;
isJogging = false;
warn("——" .. player.Name .. " will stop jogging.");
--DefaultMovement.StopJogging();
elseif not isJogging and input.KeyCode == Enum.KeyCode.W then
warn("——" .. player.Name .. " will stop running.");
--DefaultMovement.StopRunning();
end
end)
So we check the time-Window first, then we check if walking/jogging. Oh! And we added lastTick = tick(); to when the player is detected walking.
Solved it, thank you!
I had figured out that the booleans were messing things up, though I had no idea on how to solve it. Never even considered changing the order.