Hello everyone, I am writing to ask about “Why is UserInputService” so slow?
Context
I am making a 2.5D fighting game and currently, is trying to make a proper input system.
My approach:
- Have a table to store translated inputs
- Use “UserInputService” to take normal keyboard inputs and translate to the understandable inputs such as “Up, Down, Back, Forward” etc…
- Have an internal frame-clock, and in that clock after every 18 frames, the script processes the input table to find the a sequence that is the same as the sequence in the dictionary
- If there is no matching sequence, then clear the table, and if there is, then execute the function inside it and clear the table.
What’s the problem?
Just like the title said, the UserInputService is slow. It takes 3 frames to process one input and place it into the table, this is horrible for frame accurate inputs. How can I solve this?
Source Code:
local Player: Player = game.Players.LocalPlayer
local Character: Model = Player.Character or Player.CharacterAdded:Wait()
local HumanoidRootPart: Part = Character:WaitForChild('HumanoidRootPart')
local UIS = game:GetService("UserInputService")
local RunService = game:GetService("RunService")
local Melee = require(game.ReplicatedStorage.Melee).new()
local State: StringValue = Player:WaitForChild('State')
Melee:SetKeyConfigs(Melee.DefaultKeyConfig)
Melee:SetMoveset(Melee.ExampleMoveset)
UIS.InputBegan:Connect(function(input: InputObject, gameProcessedEvent: boolean)
if gameProcessedEvent then return end
if input.UserInputType == Enum.UserInputType.Keyboard then
Melee:RecordInput(input.KeyCode)
end
end)
coroutine.resume(coroutine.create(function()
local ForwardKeyConfig = {
[Enum.KeyCode.H] = "Punch",
[Enum.KeyCode.J] = "Kick",
[Enum.KeyCode.W] = "Up",
[Enum.KeyCode.S] = "Down",
[Enum.KeyCode.D] = "Forward",
[Enum.KeyCode.A] = "Back"
}
local BackwardKeyConfig = {
[Enum.KeyCode.H] = "Punch",
[Enum.KeyCode.J] = "Kick",
[Enum.KeyCode.W] = "Up",
[Enum.KeyCode.S] = "Down",
[Enum.KeyCode.D] = "Back",
[Enum.KeyCode.A] = "Forward"
}
RunService.Heartbeat:Connect(function()
if Melee.GlobalFunctions.Round(HumanoidRootPart.Orientation.Y) == 90 then
Melee:SetKeyConfigs(ForwardKeyConfig)
else if Melee.GlobalFunctions.Round(HumanoidRootPart.Orientation.Y) == -90 then
Melee:SetKeyConfigs(BackwardKeyConfig)
end
end
end)
end))
local function ProcessInputs()
local BufferBeforeFlush = Melee:GetBuffer()
if Melee:ProcessBuffer(BufferBeforeFlush) then
for _, moves in pairs(Melee:GetMoveset()) do
if moves.Name == Melee:ProcessBuffer(BufferBeforeFlush) then
if moves.AvoidState[State.Value] then
print("Supposed to be doing:", Melee:ProcessBuffer(BufferBeforeFlush), "But not because of:", State.Value)
Melee:ClearBuffer()
else
if Player:WaitForChild('CanCombo').Value == true then
moves.Action(Player)
Melee:ClearBuffer()
end
end
end
end
else
Melee:ClearBuffer()
end
end
while true do
for i = 1, 18 do
RunService.RenderStepped:Wait()
end
ProcessInputs()
end
Apologize for the spaghetti.