Help with an m1 system

So I’ve run into (yet another) issue. I have this script for m1s, but i need help making it so that if the player doesn’t press or hold m1 for a few seconds, the “Counter” will reset.

Script:

local UIS = game:GetService("UserInputService")

local RepStore = game:GetService("ReplicatedStorage")
local GameCharacter = RepStore.Characters.PlaceholderCharacter
local AssetsFolder = GameCharacter.Assets
local VFXFolder = AssetsFolder.VFX
local AnimsFolder = AssetsFolder.Animations
local RemotesFolder = GameCharacter.Remotes
local HitboxesFolder = GameCharacter.Hitboxes

local M1_1Remote = RemotesFolder.M1_1
local M1_2Remote = RemotesFolder.M1_2
local M1_3Remote = RemotesFolder.M1_3
local M1_4Remote = RemotesFolder.M1_4

local Count = 0
local Held = false
local CD = false

UIS.InputBegan:Connect(function(input)
	if input.UserInputType == Enum.UserInputType.MouseButton1 then
		if CD == false then
		Held = true
		while Held == true do
			wait(0.1)
			if Count == 0 then
				
			M1_1Remote:FireServer()
			Count = 1
			wait(0.5)
				
			elseif Count == 1 and Held == true and CD == false then
				
			M1_2Remote:FireServer()
			Count = 2
			wait(0.5)
				
			elseif Count == 2 and Held == true and CD == false then	
				
			M1_3Remote:FireServer()
			Count = 3
			wait(0.5)
				
			elseif Count == 3 and Held == true and CD == false then
			
			CD = true
			M1_4Remote:FireServer()
			Count = 4	
			wait(2)
			CD = false
			Count = 0
				end
			end
		end
	end
end)

UIS.InputEnded:Connect(function(input)
	if input.UserInputType == Enum.UserInputType.MouseButton1 then
		Held = false
		
		if CD == false then
		CD = true
		wait(0.5)
		CD = false
		end
	end
end)

You don’t have to worry about what the remote events do. Just animations and hitboxes and stuff.
Also if you could polish out other parts of the script that would be amazing. It feels very delayed when not holding and janky.

2 Likes

I don’t see why you can’t just put “Count = 0” at the end of your InputEnded event. If I’m misinterpreting your question and you actually want a delay between when the player releases their button and resetting Count, I’d check if the player is still holding the mouse button down when the delay is done with IsMouseButtonPressed. If that method returns false, reset Count.

Now onto your query about polishing the script. The first thing to improve is your InputBegan event. Instead of writing the same lines over and over again, you can just put it into a loop. If you’d like to figure out how on your own, I’ll hide my solution below. If you learn better by reading examples, feel free to open it up.

My solution to jankiness

This should replace everything past Held = true within the InputBegan event, except for any of the essential end keywords.

task.wait(0.1)
while Held and Count <= 4 do
    M1_1Remote:FireServer() -- Use unreliable remote events, if you aren't already
    Count += 1
    task.wait(0.5)
end

This solution eliminates all the if statement checks you’ve made and compresses 12 lines into 3. While I don’t think checks are too intensive on performance, this version makes your code more elegant and maintainable.

Feel free to ask any questions about unfamiliar formatting, symbols, and keywords, if there are any.

As for the delayed part, that’s exactly what wait does. To solve it, I’d use task.wait instead, since it doesn’t throttle anything and immediately resumes the script on the next heartbeat. Basically, task.wait is more accurate and is actually supported. If it’s still feeling delayed, lower the timings. 0.5 seconds is actually a pretty long time in terms of automatic gunfire.

1 Like

I would recommend using task.wait() as apposed to wait(), it’s more efficient and is better practice, anyways; this should work

local UIS = game:GetService("UserInputService")

local RepStore = game:GetService("ReplicatedStorage")
local GameCharacter = RepStore.Characters.PlaceholderCharacter
local AssetsFolder = GameCharacter.Assets
local VFXFolder = AssetsFolder.VFX
local AnimsFolder = AssetsFolder.Animations
local RemotesFolder = GameCharacter.Remotes
local HitboxesFolder = GameCharacter.Hitboxes

local M1_1Remote = RemotesFolder.M1_1
local M1_2Remote = RemotesFolder.M1_2
local M1_3Remote = RemotesFolder.M1_3
local M1_4Remote = RemotesFolder.M1_4

local Count = 0
local Held = false
local CD = false

local HeldCheckConnection = nil

UIS.InputBegan:Connect(function(input, gamePaused)
	if gamePaused then return end -- cancels script if player is typing/in menu
	if input.UserInputType == Enum.UserInputType.MouseButton1 then
		if CD == false then
			Held = true
			
			if HeldCheckConnection then -- checks if the variable task exists
				task.cancel(HeldCheckConnection) -- if it does then disconnect it and cancel it
				HeldCheckConnection = nil
			end
			
			while Held == true and CD == false do
				Count += 1 -- adds 1 to the count
				RemotesFolder["M1_".. tostring(Count)]:FireServer() -- fires the M1 event related to the count number automatically
				
				if Count >= 4 then -- cheks if the count is 4 or over
					CD = true -- activates cooldown
					task.delay(2, function() -- sets this task function to activate after 2 seconds
						CD = false
						Count = 0
					end)
				else
					task.wait(0.5) -- waits 0.5 seconds
				end
			end
		end
	end
end)

UIS.InputEnded:Connect(function(input)
	if input.UserInputType == Enum.UserInputType.MouseButton1 then
		Held = false
		
		HeldCheckConnection = task.delay(2, function() -- creates a variable task that activates after 2 seconds
			Count = 0
		end)
	end
end)
1 Like

Thank you! This works perfectly and feels so much better!

2 Likes

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.