Hello, I’m trying to make an input buffer the issue is I don’t know how to make one haha so it has been quite a process luckily though there are a few good articles that I found that give some insight into how to make one. The one I hyperlinked is what I’m currently using and I’m having difficulties being able to translate what is being said to actual code.
The first part of the article basically talks about how you should map actions to numbers instead of actions to buttons as it makes things easier in the long run and I managed to get this part done using the bit32 functions (had to dig a bit to find out this existed)
Edit: for anyone that might be intimidated by the code below it’s basically just Up = 4, Down = 2, Right = 8, etc and when a key is pressed the number is added to a variable which in this case is self.inputs and I can then use this to check what buttons are pressed if self.inputs is 12 I know Up + Right is being pressed since 4 + 8 is 12 and then when a key is released the number is subtracted.
Enums.InputButtons = {
Neutral_Input = bit32.lshift(1, 18),
None = 0,
Down_Direction = bit32.lshift(1, 0),
Left_Direction = bit32.lshift(1, 1),
Up_Direction = bit32.lshift(1, 2),
Right_Direction = bit32.lshift(1, 3),
DownLeft_Direction = bit32.bor(bit32.lshift(1, 0), bit32.lshift(1, 1)),
DownRight_Direction = bit32.bor(bit32.lshift(1, 0), bit32.lshift(1, 3)),
UpLeft_Direction = bit32.bor(bit32.lshift(1, 2), bit32.lshift(1, 1)),
UpRight_Direction = bit32.bor(bit32.lshift(1, 2), bit32.lshift(1, 3)),
TaptoHoldButtonShift = 19,
HeldDown_Direction = bit32.lshift(bit32.lshift(1, 0), 19),
Guard_Button = bit32.lshift(1, 4),
Punch_Button = bit32.lshift(1, 5),
Kick_Button = bit32.lshift(1, 6),
Tech_Button = bit32.lshift(1, 7),
Trigger_Button = bit32.lshift(1, 8),
Selection_Button = bit32.lshift(1, 9),
Cancel_Button = bit32.lshift(1, 10),
Modifier_Button = bit32.lshift(1, 11),
Menu_Pause_Button = bit32.lshift(1, 12),
}
And then this is my input module where you can see how the above code gets used and it works quite well.
function Input.new()
local self = setmetatable({},Input)
self.buffer = InputBuffer.new()
self.inputs = 0
self.keybinds = {
["Left"] = Enum.KeyCode.A,
["Right"] = Enum.KeyCode.D,
["Up"] = Enum.KeyCode.W,
["Down"] = Enum.KeyCode.S,
["LightAttack"] = Enum.KeyCode.H,
}
self.keymap = {
[self.keybinds["Left"]] = inputButtons.Left_Direction,
[self.keybinds["Right"]] = inputButtons.Right_Direction,
[self.keybinds["Up"]] = inputButtons.Up_Direction,
[self.keybinds["Down"]] = inputButtons.Down_Direction,
[self.keybinds["LightAttack"]] = inputButtons.Punch_Button,
}
UserInputService.InputBegan:Connect(function(inputObject, gameProcessed)
self:inputBegan(inputObject, gameProcessed)
end)
UserInputService.InputEnded:Connect(function(inputObject, gameProcessed)
self:inputEnded(inputObject, gameProcessed)
end)
return self
end
function Input:inputBegan(inputObject, gameProcessed)
if gameProcessed then
return
end
-- don't care about anything that's not the keyboard
if inputObject.UserInputType ~= Enum.UserInputType.Keyboard then
return
end
-- gonna be something like 8, 2, 4, etc
local input = self.keymap[inputObject.KeyCode]
-- set the input bit in the inputs number
self.inputs = bit32.bor(self.inputs, input)
end
function Input:inputEnded(inputObject, gameProcessed)
if gameProcessed then
return
end
if inputObject.UserInputType ~= Enum.UserInputType.Keyboard then
return
end
local input = self.keymap[inputObject.KeyCode]
-- unset the input bit in the inputs number
self.inputs = bit32.band(self.inputs, bit32.bnot(input))
end
The next part of the article is actually storing commands/input which is where I start to get stuck. I know I need a table or dictionary to store things, but the article talks about this being something that happens every frame (ex: Frame #1 left was pressed, Frame #2 nothing was pressed, Frame #3 left and punch was pressed, etc) and only storing inputs if they weren’t pressed before instead of continuously and I haven’t been able to figure out how to get around this.
This is the code I tried doing, but I don’t think it’s that effective.
local keysPressedLastFrame = {}
function Input:update()
local keysPressedThisFrame = UserInputService:GetKeysPressed()
local newKeysPressed = {}
for index,inputObject in pairs(keysPressedThisFrame) do
if not keysPressedLastFrame[index] then
newKeysPressed[index] = inputObject.KeyCode
end
end
keysPressedLastFrame = keysPressedThisFrame
print("New keys pressed this frame",newKeysPressed)
end
-- In client module being ran every frame
local function processFrame(deltaTime)
localFrame += 1
input:update()
end