How to replicated the double flick with gaming controller sprinting from Minecraft

I want to make a game mechanic that when you using a gaming controller to sprint inside the game, you can double flick the left joystick
Can someone please show me how to do it?

2 Likes

Well, I’m not giving you code.

  1. I’m on my phone right now.
  2. Its better to learn it yourself, with advice.

You want to save a variable for the current system time, use tick(), whenever the player moves forward with their joystick. Before setting the variable, check weather that variable and the current tick() is between a number amount of seconds (easiest way is to subtract both numbers together, so like lastTime - tick()). If its under 0.4 seconds its fair to determine the player wants to sprint, so set their speed.

A more accurate way would be using renderstepped and using frametime instead of tick. But that’s a little tiny bit more advanced and you can always modify your code in the future.

Then when the joystick returns to 0,0 you set speed back to default.

The problem with tick() is that it’s deprecated, but I also need to know if UserInputService has a feature for that or it’s something

As far as I’m aware there isn’t a feature of UserInputService or InputContext service that listens to joystick flicking as an action, so you’ll have to create your own solution. You can do this by listening to when the gamepad input changes for the joystick - when it reaches fully forward, keep track of the timestamp so that when the input changes back down you can compare how long the stick was held forward. If the duration was short enough (e.g. <0.3s) you can consider it a flick.

You can timestamp this too, so if the stick is flicked for a second time, you can activate sprinting!

Input Action System | Documentation - Roblox Creator Hub offers that function set it up, make the keycode something like gamepad joystick thumbstick1 and then read the input2direction. But there should be a pressed input event

local userInputService = game:GetService('UserInputService')
local players = game:GetService('Players')
local localPlayer = players.LocalPlayer
local character = localPlayer.Character or localPlayer.CharacterAdded:Wait()

userInputService.InputBegan:Connect(function(input, gameProcessedEvent)

   if gameProcessedEvent then return end

   if input.KeyCode == Enum.KeyCode.ThumbstickUp then

        if input.KeyCode == Enum.KeyCode.ThumbstickUp then

         character.Humanoid.WalkSpeed = 30

        end
   end
end)

userInputService.InputEnded:Connect(function(input, gameProcessedEvent)

   if gameProcessedEvent then return end

   if input.KeyCode == Enum.KeyCode.ThumbstickUp then

        if input.KeyCode == Enum.KeyCode.ThumbstickUp then

         character.Humanoid.WalkSpeed = 16

        end
   end
end)

Will this work?

No. It will just immediately sprint because if the first if is true the second if is just the same. Didn’t you get a warning in studio?

It’s not officially deprecated; it’s just not recommended by people with schizophrenia thinking it has some sort of issues. They put it in tick() documentation because it was a big deal.

It’s exactly the same as os.time() and I’ve been using tick() for a very long time because I think it looks better personally.

Would this work?

local UserInputService = game:GetService("UserInputService")
local keycode = Enum.KeyCode.Thumbstick1Up
local last = os.clock()
local flickduration = 0.4
UserInputService.InputBegan:Connect(function(input,gameprocessed)
    if not gameprocessed then
		if input.KeyCode == keycode then
			if os.clock() - last < flickduration then
				print("Sprint start")
			end
            last = os.clock()
		end
	end
end)

I would recommend using the new InputActions so you can seamlessly add new binds easily. Plus, if you’re worried about future deprecation of UIS then you won’t have to worry about updating it.

You should also not be using os.clock() for anything besides logging or benchmarking, because lag will cause it to slow down. Instead use DateTime.now().UnixTimestampMillis for milisecond accuracy from Unix time.

local Forward = script:FindFirstChild("Forward") :: InputAction

local Speed = 5
local running = false
local lastPress = DateTime.now().UnixTimestampMillis

Forward.Pressed:Connect(function()
	if running == false and (DateTime.now().UnixTimestampMillis - lastPress)/1000 < 0.4 then --// Subtract the current time by the last pressed time, then divide it by 1000 to bring it to accurate seconds, so 0.5 is half a second for example. Adjust 0.4 for sensitivity.
		running = true
		print("Running (test)")
		--Character.Humanoid.WalkSpeed += Speed -- You should add speed, not set it. So when you have like a speed boost in your game you just add the speed boost and then subtract it and your life will be easy!
	end
	lastPress = DateTime.now().UnixTimestampMillis
end)

Forward.Released:Connect(function()
	if running == true then
		--Character.Humanoid.WalkSpeed -= Speed
		print("Stop")
		running = false
	end
end)