How can i improve my input detection scripts?

I’m planning on making some vehicles, and so i did this little test to learn how to detect input efficiently.

However, my code looks rather viscous, and i want to know how can i get rid of this aspect of it, if possible.

There are 2 scripts that build this contraption in total:
ServerScript ArrowsManager, parented to the contraption’s model
LocalScript Controller, parented to ArrowsManager

ArrowsManager

local Arrows = script.Parent:FindFirstChild("Arrows") or script.Parent:WaitForChild("Arrows")
local Seat = script.Parent:FindFirstChild("Seat") or script.Parent:WaitForChild("Seat")
local ToggleEvent = Seat:FindFirstChild("Toggle") or Seat:WaitForChild("Toggle")
local ControllerScript = script:FindFirstChild("Controller") or script:WaitForChild("Controller")

local InputTable = {
	KEYW = Enum.KeyCode.W;
	KEYA = Enum.KeyCode.A;
	KEYS = Enum.KeyCode.S;
	KEYD = Enum.KeyCode.D
}

ToggleEvent.OnServerEvent:Connect(function(Player,Bool,Key)
	if Bool then
		if Key == InputTable.KEYW then
			print("pressed w")
			Arrows.Forward.Material = Enum.Material.Neon
		elseif Key == InputTable.KEYA then
			Arrows.Left.Material = Enum.Material.Neon
		elseif Key == InputTable.KEYS then
			Arrows.Back.Material = Enum.Material.Neon
		elseif Key == InputTable.KEYD then
			Arrows.Right.Material = Enum.Material.Neon
		end
	else
		if Key == InputTable.KEYW then
			print("unpressed w")
			Arrows.Forward.Material = Enum.Material.Plastic
		elseif Key == InputTable.KEYA then
			Arrows.Left.Material = Enum.Material.Plastic
		elseif Key == InputTable.KEYS then
			Arrows.Back.Material = Enum.Material.Plastic
		elseif Key == InputTable.KEYD then
			Arrows.Right.Material = Enum.Material.Plastic
		end
	end
end)

Seat:GetPropertyChangedSignal("Occupant"):Connect(function()
	if Seat.Occupant then
		ControllerScript:Clone().Parent = Seat.Occupant.Parent
	end
end)

Controller

local UserInputService = game:GetService("UserInputService")

local Character = script.Parent
local Humanoid = Character.Humanoid
local Toggle = Humanoid.SeatPart.Toggle

UserInputService.InputBegan:Connect(function(Key,IsTyping)
	if not IsTyping then
		Toggle:FireServer(true,Key.KeyCode)
	end
end)

UserInputService.InputEnded:Connect(function(Key,IsTyping)
	if not IsTyping then
		Toggle:FireServer(false,Key.KeyCode)
	end
end)

Humanoid.Seated:Connect(function(Bool)
	if not Bool then
		script:Destroy()
	end
end)

I hope its understandable :pensive:

You could instead map the KeyCodes to the arrows like this

local InputTable = {
    Enum.KeyCode.W = Arrows.Forward,
    Enum.KeyCode.A = Arrows.Left,
    ...
}

Then your OnServerEvent can be

if Bool then
    local arrow = InputTable[Key]
    if arrow then
        arrow.Material = Enum.Material.Neon
    end
else
   -- same idea
end
2 Likes

The A:FindFirstChild(B) or A:WaitForChild(B) isn’t necessary. WaitForChild already checks if the child exists before waiting.

For context-based actions it is also advisable you use ContextActionService over UserInputService; it even handles the gameProcessedEvent flag and such for you.

Since you’re relying on events for the movement there may be some latency in your final game. You should consider handling the movement on the client by giving network ownership of the vehicle to the player when they sit on it and giving it back to the server when they leave. Alongside that make sure you have the proper sanity checks for distance on the server.

5 Likes

Very useful, but there’s a error when i write it:
Capturar

The error says:
" Syntax error: Expected ‘}’ (to close ‘{’ at line 8), got ‘=’ "

Edit: i forgot to include the commas, but the error doesn’t go away either

Oh I forgot about that. Wrap the keys in brackets.

[Enum.KeyCode.W] = Arrows.Forward,

etc.

1 Like