Movement action is not instant [SOLVED]

Hello, I’ve stumble on an issue which I cannot find any solutioj on the forum.
I was making movement system with module, for now it just basic function with no animation yet.

However, I’ve noticed that the movement action are not instant.

Let’s say when a player is currently in ‘sprinting action’, when pressing crouch the action instantly turn to ‘crouch action’.

But the issue I have is that when player are changing action there’s a gap that caused the player action to return to default not turning action into ‘sprinting’ or ‘crouch’.

Video:

Module script:

-- // Services
local TweenService = game:GetService("TweenService")
local StarterPlayer = game:GetService("StarterPlayer")

-- // Tween Info

local Info = TweenInfo.new(1.2, Enum.EasingStyle.Exponential, Enum.EasingDirection.Out)

-- // MovementHandler
local MovementHandler = {}

-- // Local Player
local Player = game:GetService("Players").LocalPlayer

local Character = Player.Character
local Humanoid = Character:WaitForChild("Humanoid")
local Animator = Humanoid:WaitForChild("Animator")

-- // Folders


-- // Values


-- // States
MovementHandler.States = {}
MovementHandler.States.Sprinting = false
MovementHandler.States.Crouching = false

-- // Properties
MovementHandler.Properties = {}
MovementHandler.Properties.WalkSpeed = 16
MovementHandler.Properties.SprintSpeed = 50
MovementHandler.Properties.CrouchSpeed = 3

-- // Functions
function MovementHandler:StartSprinting()
	print("StartSprinting")
	if MovementHandler.States.Crouching then
		MovementHandler.States.Crouching = false
		MovementHandler:StopCrouching()
	end
	MovementHandler.States.Sprinting = true
	TweenService:Create(Humanoid, Info, {WalkSpeed = MovementHandler.Properties.SprintSpeed}):Play()
end

function MovementHandler:StopSprinting()
	print("StopSprinting")
	MovementHandler.States.Sprinting = false
	TweenService:Create(Humanoid, Info, {WalkSpeed = MovementHandler.Properties.WalkSpeed}):Play()
end

function MovementHandler:StartCrouching()
	print("StartCrouching")
	if MovementHandler.States.Sprinting then
		MovementHandler.States.Sprinting = false
		MovementHandler:StopSprinting()
	end
	MovementHandler.States.Crouching = true
	TweenService:Create(Humanoid, Info, {WalkSpeed = MovementHandler.Properties.CrouchSpeed}):Play()
end

function MovementHandler:StopCrouching()
	print("StopCrouching")
	MovementHandler.States.Crouching = false
	TweenService:Create(Humanoid, Info, {WalkSpeed = MovementHandler.Properties.WalkSpeed}):Play()
end

return MovementHandler

(look at the replys for more informations)

I can’t see the video, but my assumption is that this may be caused due to latency that is naturally present between the server and the client. Any time you communicate between the two, the signal has to travels some distance which creates the feeling of non-instataneousness

Hey, I put the code in correct format now.
Any issue with the code?

I also forgot to mention that there are no error in the output.

TweenService:Create(Humanoid, Info, {WalkSpeedMovementHandler.Properties.SprintSpeed}):Play()

Play() may be yielding, which means code execution can’t move until the tween is complete. I’m not entirely sure if Play() yields, but if it does, you are going to have to wait for each of these tweens to be completed which could cause the delay you may be experiencing

1 Like

I’ve tried your method. Unfortunately, the result is still the same as before.

I copied and pasted your module and tested it myself. It seemed to work just fine. Perhaps it has something to do with the code that listens for when you click these buttons?

Did you use UserInputService or ContextActionService?

ContextActionService. It worked fine when I pressed both the key (left shift and left ctrl in my case) and the mobile buttons.

I was using UserInputService because I’m not professional in ContextActionService. :disappointed_relieved:

Can you send the code where you use it? UserInputService should work just fine too.

1 Like

Sure, give me a moment.

MobileButtons.SprintButton.MouseButton1Down:Connect(function()
	if not Activated then
		Activated = true
		MovementHandler:StartSprinting()
	else
		Activated = false
		MovementHandler:StopSprinting()
	end
end)

MobileButtons.CrouchButton.MouseButton1Down:Connect(function()
	if not Activated then
		Activated = true
		MovementHandler:StartCrouching()
	else
		Activated = false
		MovementHandler:StopCrouching()
	end
end)

UserInputService.InputBegan:Connect(function(Input)
	if Input.KeyCode == Enum.KeyCode.LeftShift then
		if not Activated then
			Activated = true
			MovementHandler:StartSprinting()
		else
			Activated = false
			MovementHandler:StopSprinting()
		end
	end
end)

UserInputService.InputBegan:Connect(function(Input)
	if Input.KeyCode == Enum.KeyCode.C then
		if not Activated then
			Activated = true
			MovementHandler:StartCrouching()
		else
			Activated = false
			MovementHandler:StopCrouching()
		end
	end
end)

I included the mobile code too because it has the same problem.

I see the problem. All of these functions share the same Activated value. Here’s a scenario: The player presses LeftShift, which sets Activated = true. They then press C. Activated is still equal to true.

This would check if Activated is equal to false, which it is not, and since it is not, StopCrouching is what is called. Since you keep values of the states inside of the module, I suggest you just use those:

MobileButtons.SprintButton.MouseButton1Down:Connect(function()
	if not MovementHandler.States.Sprinting then
		MovementHandler:StartSprinting()
	else
		MovementHandler:StopSprinting()
	end
end)

MobileButtons.CrouchButton.MouseButton1Down:Connect(function()
	if not MovementHandler.States.Crouching then
		MovementHandler:StartCrouching()
	else
		MovementHandler:StopCrouching()
	end
end)

UserInputService.InputBegan:Connect(function(Input)
	if Input.KeyCode == Enum.KeyCode.LeftShift then
		if not MovementHandler.States.Sprinting then
			MovementHandler:StartSprinting()
		else
			MovementHandler:StopSprinting()
		end
	end
end)

UserInputService.InputBegan:Connect(function(Input)
	if Input.KeyCode == Enum.KeyCode.C then
		if not MovementHandler.States.Crouching then
			MovementHandler:StartCrouching()
		else
			MovementHandler:StopCrouching()
		end
	end
end)
1 Like

Alright, I’ll try this right now.

Yipeee, it work like I wanted. Thank you!