Help with creating an input system for a fighting game

I’m currently working on a game that’ll utilize movesets for specific characters, but I am drawing a blank on how to properly implement a certain feature of it.

Each ability has two different casts, a quick cast, which is just a simple key press, and a held cast, which allows the player to take the time to aim an ability, as well as see the range of said ability (think of League of Legends when you hold an ability before casting.) I am struggling to figure out how to implement both types of casts in one local script.

I use a module script to handle inputs across the board since they will be universal for every player, and a bit of it is as follows:

local PrimaryAbilityEvent = Instance.new("BindableEvent")

local InputHandler = {
	PrimaryAbility = PrimaryAbilityEvent.Event,
}

table.insert(EventsToDisconnect, UserInput.InputBegan:Connect(function(Input, Processed)
	if Processed then return end
	local Character = Player.Character
	if not Character then return end
	local Humanoid = Character:FindFirstChildOfClass("Humanoid")
	if not Humanoid or Humanoid.Health <= 0 then return end

	--DisconnectEvents()

	if Input.UserInputType == Enum.UserInputType.MouseButton2 then
		MouseClickEvent:Fire(Input.Position.X, Input.Position.Y)
	elseif Input.UserInputType == Enum.UserInputType.Keyboard then
		if Input.KeyCode == Enum.KeyCode.Q then
			PrimaryAbilityEvent:Fire()
		--elseif Input.KeyCode == Enum.KeyCode.W then
			
		elseif Input.KeyCode == Enum.KeyCode.E then
			
		end
	end
end))

Essentially I just create BindableEvents and just attach them to input keys, where they get fired to the client whenever a player presses a button. When a player does hit something, it gets sent to their local client like this:

local IsHeld = false
local IsKeyActive = false
local ActiveKey = nil

InputHandler.PrimaryAbility:Connect(function() 
	
end)

Run.RenderStepped:Connect(function()
	if UserInput:IsKeyDown(Enum.KeyCode.Q) 
		or UserInput:IsKeyDown(Enum.KeyCode.E) 
	then
		IsHeld = true
	else
		IsHeld = false
	end
end)

Where I draw the blank is how I am meant to both detect whether a key is being pressed and when it is being held, as I am only able to detect when the key is pressed in my BindableEvent. I thought using RenderStepped could be a workaround for this, but if the bindable event only fires once, it will never actually detect it being held down.

Any insight or previous experience would be very, very helpful.

A possible solution could be waiting a little bit after the initial button press, and then checking if the button is still held down. If it isn’t being held down, then it was just a standard key press. If it is still held down, then they are holding down the button.

2 Likes

Thanks for the answer! Typed up a solution (for now) and so far it’s going well.

InputHandler.PrimaryAbility:Connect(function(Input)
	Run.RenderStepped:Wait()
	
	if UserInput:IsKeyDown(Input.KeyCode) then
		--stuff
	else
		--stuff part 2
	end
end)