This has already been achieved by numerous games such as:
To be more specific, I am talking about an in game feature in these games. In order to test it, simply m1/left click once and wait about 2 seconds. Voila! your back at the first m1 of 4.
Now, How would you do this:
Using tick() or os.clock() maybe?
Here is the code which I am trying to put this in…
--!strict
local M1Module = {}
M1Module.__index = M1Module
--//Services
local Players = game:GetService("Players")
local DebrisService = game:GetService("Debris")
local RunService = game:GetService("RunService")
local TweenService = game:GetService("TweenService")
local StarterPlayer = game:GetService("StarterPlayer")
local UserInputService = game:GetService("UserInputService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local ServerScriptService = game:GetService("ServerScriptService")
--//Modules
local Modules = ReplicatedStorage.Modules
local Utilites = require(script.Utilities)
local HitboxModule = require(Modules.Manager.Character.Hitbox.Hitbox)
local CooldownModule = require(Modules.Manager.Character.Utility.Cooldown)
local Controllers = script.Parent.Parent
local AnimationManger = require(Modules.Manager.Character.AnimationManager)
local MaidModule = require(Modules.Utility.Maid)
local Maid = MaidModule.new()
--//Resources
local ReplicatedAssets = ReplicatedStorage.Assets
local Animations = ReplicatedAssets.Animations
local Remotes = ReplicatedStorage.Communication.Remotes
local SFX = ReplicatedAssets.SFX
local VFX = ReplicatedAssets.Effects
--//Global Variables
local Player = Players.LocalPlayer
local Character = Player.Character
local Humanoid = Character:WaitForChild("Humanoid")
local Animator = Humanoid:WaitForChild("Animator")
local RootPart = Character:WaitForChild("HumanoidRootPart")
local Camera = workspace.CurrentCamera
local Mouse = Player:GetMouse()
--//Booleans/Variables
local M1Bindable = script.Bindable
local M1ToMovement = script.Parent.Parent.Movement.Sprint.Bindable
local HitboxEvent = Remotes.Hitbox.Hitbox
local CurrentM1 = 1
local PastM1 = CurrentM1 - 1
local NextM1 = CurrentM1 + 1
local MaxM1 = 4
local M1Debounce = false
local MaxM1Debounce = false
local M1DebounceTime = 0.4
local MaxM1DebounceTime = 3
local M1Clock = tick()
local Cooldowns = {}
--//Animations
local CombatAnimations = Animations.Combat.Shared
local M1CombatAnimations = CombatAnimations["M1's"]
local DowmsmashCombatAnimation = Animator:LoadAnimation(M1CombatAnimations.Special.Downsmash)
local UptiltCombatAnimation = Animator:LoadAnimation (M1CombatAnimations.Special.Uptilt)
--//Sounds
local CombatSounds = SFX.Combat.Shared
local M1SwingSounds = CombatSounds.M1.Swings
local M1HitSounds = CombatSounds.M1.Hits
--//OnInvoke
M1Bindable.OnInvoke = function()
if Cooldowns["M1Cooldown"] == true then return end
local OldM1 = CurrentM1
print(OldM1)
local CurrentAnimation = M1CombatAnimations:FindFirstChild("M1 ("..OldM1..")")
local M1Animation = Animator:LoadAnimation(CurrentAnimation)
M1Animation:Play()
Maid:GiveTask(task.spawn(function()
M1Animation:GetMarkerReachedSignal("Hit"):Connect(function()
HitboxEvent:FireServer(RootPart,Humanoid,"M1")
local CurrentSwingSound = M1SwingSounds:FindFirstChild(OldM1)
CurrentSwingSound:Play()
end)
M1Animation:GetMarkerReachedSignal("Finish"):Connect(function()
local CurrentHitSound = M1HitSounds:FindFirstChild(OldM1)
CurrentHitSound:Play()
end)
Maid:GiveTask(task.spawn(function()
M1ToMovement:Invoke()
end))
Maid:GiveTask(task.spawn(function()
Utilites.SlowWhileInM1(M1Animation)
end))
end))
if OldM1 >= MaxM1 then
CurrentM1 = 1
CooldownModule:AddCooldown("M1Cooldown",MaxM1DebounceTime,Cooldowns)
else
CurrentM1 += 1
CooldownModule:AddCooldown("M1Cooldown",M1DebounceTime,Cooldowns)
end
--[[
if tick() - M1Clock <= 2.5 then
CurrentM1 = 1
end
--]]
end
when you do your 4th m1 have a variable called “lastM1Combo” or something you prefer, and set it to os.clock. then add a check if (os.clock() - lastM1Combo) > 2
--!strict
local M1Module = {}
M1Module.__index = M1Module
--//Services
local Players = game:GetService("Players")
local DebrisService = game:GetService("Debris")
local RunService = game:GetService("RunService")
local TweenService = game:GetService("TweenService")
local StarterPlayer = game:GetService("StarterPlayer")
local UserInputService = game:GetService("UserInputService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local ServerScriptService = game:GetService("ServerScriptService")
--//Modules
local Modules = ReplicatedStorage.Modules
local Utilites = require(script.Utilities)
local HitboxModule = require(Modules.Manager.Character.Hitbox.Hitbox)
local CooldownModule = require(Modules.Manager.Character.Utility.Cooldown)
local Controllers = script.Parent.Parent
local AnimationManger = require(Modules.Manager.Character.AnimationManager)
local MaidModule = require(Modules.Utility.Maid)
local Maid = MaidModule.new()
--//Resources
local ReplicatedAssets = ReplicatedStorage.Assets
local Animations = ReplicatedAssets.Animations
local Remotes = ReplicatedStorage.Communication.Remotes
local SFX = ReplicatedAssets.SFX
local VFX = ReplicatedAssets.Effects
--//Global Variables
local Player = Players.LocalPlayer
local Character = Player.Character
local Humanoid = Character:WaitForChild("Humanoid")
local Animator = Humanoid:WaitForChild("Animator")
local RootPart = Character:WaitForChild("HumanoidRootPart")
local Camera = workspace.CurrentCamera
local Mouse = Player:GetMouse()
--//Booleans/Variables
local M1Bindable = script.Bindable
local M1ToMovement = script.Parent.Parent.Movement.Sprint.Bindable
local HitboxEvent = Remotes.Hitbox.Hitbox
local CurrentM1 = 1
local PastM1 = CurrentM1 - 1
local NextM1 = CurrentM1 + 1
local MaxM1 = 4
local M1Debounce = false
local MaxM1Debounce = false
local M1DebounceTime = 0.4
local MaxM1DebounceTime = 3
local M1Clock = os.clock()
local Cooldowns = {}
--//Animations
local CombatAnimations = Animations.Combat.Shared
local M1CombatAnimations = CombatAnimations["M1's"]
local DowmsmashCombatAnimation = Animator:LoadAnimation(M1CombatAnimations.Special.Downsmash)
local UptiltCombatAnimation = Animator:LoadAnimation (M1CombatAnimations.Special.Uptilt)
--//Sounds
local CombatSounds = SFX.Combat.Shared
local M1SwingSounds = CombatSounds.M1.Swings
local M1HitSounds = CombatSounds.M1.Hits
--//OnInvoke
M1Bindable.OnInvoke = function()
if Cooldowns["M1Cooldown"] == true then return end
if os.clock() - M1Clock > 2.5 then
CurrentM1 = 1
end
M1Clock = os.clock()
local OldM1 = CurrentM1
print(OldM1)
local CurrentAnimation = M1CombatAnimations:FindFirstChild("M1 ("..OldM1..")")
local M1Animation = Animator:LoadAnimation(CurrentAnimation)
M1Animation:Play()
Maid:GiveTask(task.spawn(function()
M1Animation:GetMarkerReachedSignal("Hit"):Connect(function()
HitboxEvent:FireServer(RootPart,Humanoid,"M1")
local CurrentSwingSound = M1SwingSounds:FindFirstChild(OldM1)
CurrentSwingSound:Play()
end)
M1Animation:GetMarkerReachedSignal("Finish"):Connect(function()
local CurrentHitSound = M1HitSounds:FindFirstChild(OldM1)
CurrentHitSound:Play()
end)
Maid:GiveTask(task.spawn(function()
M1ToMovement:Invoke()
end))
Maid:GiveTask(task.spawn(function()
Utilites.SlowWhileInM1(M1Animation)
end))
end))
if OldM1 >= MaxM1 then
CurrentM1 = 1
CooldownModule:AddCooldown("M1Cooldown",MaxM1DebounceTime,Cooldowns)
else
CurrentM1 += 1
CooldownModule:AddCooldown("M1Cooldown",M1DebounceTime,Cooldowns)
end
end
By the way, tick() differs from os.clock() in that tick() is already slowly starting to become obsolete and os.clock() is its worthwhile replacement