Simple Binding Module

This module is targeted toward beginners and others alike.

local UIS = game:GetService("UserInputService")

type InputData = Enum.KeyCode | Enum.UserInputType
type MappingData = { [InputData]: (InputState: Enum.UserInputState) -> () | nil }

local BindMap = {}
BindMap._map = nil
BindMap._nil = function() end

local function _RunMap(index: InputData, ...)
	local Callback = BindMap._map[index]
	if Callback then
		Callback(...)
	end
end

local function ForPairs(t, callback)
	for index, value in pairs(t) do
		callback(index, value)
	end
end

local function OnInput(input, gpe)
	if not gpe then
		local CaughtInput = (input.KeyCode == Enum.KeyCode.Unknown) and input.UserInputType or input.KeyCode
		_RunMap(CaughtInput, input.UserInputState)
	end
end

function BindMap.map(NewMap: MappingData) --// Overwrite all data
	BindMap._map = NewMap
end

function BindMap.softMap(NewMap) --// Add those which do not exist
	print(NewMap)
	if BindMap._map == nil then
		BindMap._map = NewMap
		return
	end
	ForPairs(NewMap, function(input, callback)
		if BindMap._map[input] == nil then
			BindMap._map[input] = callback or nil
		end
	end)
end

function BindMap.hardMap(NewMap) --// Override those which exist already.
	if BindMap._map == nil then
		return
	end
	ForPairs(NewMap, function(input, callback)
		if BindMap._map[input] ~= nil then
			BindMap._map[input] = callback or nil
		end
	end)
end

function BindMap.crossMap(NewMap: MappingData) --// Will overwrite existing variables without removing entire data
	BindMap.hardMap(NewMap)
	BindMap.softMap(NewMap)
end

UIS.InputBegan:Connect(OnInput)
UIS.InputEnded:Connect(OnInput)
UIS.InputChanged:Connect(OnInput)

return BindMap

Example Usage

local Directive = {
    Run = function(state)
        if state == Enum.UserInputState.End then
            print("Requested to stop running!")
        end
    end,
    Dash = function(state)
        if state == Enum.UserInputState.Begin then
            print("Request to dash!")
        end
    end,
    Zoom = function(state)
        if state == Enum.UserInputState.Change then
            print("Zoom is changing currently...")
        end
    end,
}

Binding.map({
    [Enum.KeyCode.LeftShift] = Directive.Run,
    [Enum.KeyCode.LeftControl] = Directive.Dash,
    [Enum.UserInputType.MouseWheel] = Directive.Zoom,
}) --// Completely overwrite everything

Binding.hardMap({
    [Enum.KeyCode.LeftShift] = Binding._nil,
})
--// Edit existing item. Wont work if the item does not exist.

Binding.softMap({
    [Enum.KeyCode.LeftShift] = function(state)
        print("I tried to overwrite")
    end,
}) --// Will not work because the value exist. Only adds something if it doesnt exist.

Binding.crossMap({
    [Enum.KeyCode.LeftControl] = function(state)
        print("I edited this!")
    end,
}) --// Rewrite data without overwriting entire table Adding, editing, or removing it...

Note: This is just a straight forward module. Easy to use and setup. Nothing complex was added because this is meant to be as simple and plain as possible.

12 Likes

Would like to add this is extremely raw, nothing special in any way.

1 Like

You may want to add that this is for keybinding to actions for new scripters.

Other than that, does what it’s supposed to. Good job. :clap:

Just added that into the post. Should’ve clarified that :+1:. Thanks!

Do you think it’s possible for me to make this mobile compatible?

Unless its under the Enum.KeyCode or Enum.UserInputType. I don’t believe you can. ContextActionService may be your best bet ContextActionService | Documentation - Roblox Creator Hub

3 Likes