Skip to content

Instantly share code, notes, and snippets.

@spotco
Created September 17, 2020 00:22
Show Gist options
  • Save spotco/7b36b5c40e76838d7b5bf20e99cb8d11 to your computer and use it in GitHub Desktop.
Save spotco/7b36b5c40e76838d7b5bf20e99cb8d11 to your computer and use it in GitHub Desktop.
InputUtil main Robeats
local SPUtil = require(game.ReplicatedStorage.Shared.SPUtil)
local SPDict = require(game.ReplicatedStorage.Shared.SPDict)
local SPList = require(game.ReplicatedStorage.Shared.SPList)
local SPVector = require(game.ReplicatedStorage.Shared.SPVector)
local InputUtil = {}
InputUtil.KEY_TRACK1 = 0
InputUtil.KEY_TRACK2 = 1
InputUtil.KEY_TRACK3 = 2
InputUtil.KEY_TRACK4 = 3
InputUtil.KEY_POWERBAR_TRIGGER = 4
InputUtil.KEY_GAME_QUIT = 5
InputUtil.KEY_UP = 10
InputUtil.KEY_DOWN = 11
InputUtil.KEY_LEFT = 12
InputUtil.KEY_RIGHT = 13
InputUtil.KEY_A = 14
InputUtil.KEY_B = 15
InputUtil.KEY_MOD1 = 21
InputUtil.KEY_MENU_OPEN = 31
InputUtil.KEY_MENU_ENTER = 32
InputUtil.KEY_MENU_BACK = 33
InputUtil.KEY_MENU_MATCHMAKING_CHAT_FOCUS = 34
InputUtil.KEY_CHAT_WINDOW_FOCUS = 35
InputUtil.KEY_MENU_SPUITEXTINPUT_ESC = 36
InputUtil.KEY_CLICK = 41
InputUtil.KEY_SCROLL_UP = 51
InputUtil.KEY_SCROLL_DOWN = 52
InputUtil.KEY_DEBUG_1 = 100
InputUtil.KEY_DEBUG_2 = 101
InputUtil.KEY_DEBUG_3 = 102
InputUtil.KEY_DEBUG_4 = 103
InputUtil.KEYCODE_TOUCH_TRACK1 = 10001
InputUtil.KEYCODE_TOUCH_TRACK2 = 10002
InputUtil.KEYCODE_TOUCH_TRACK3 = 10003
InputUtil.KEYCODE_TOUCH_TRACK4 = 10004
function InputUtil:new()
local self = {}
local userinput_service = game:GetService("UserInputService")
local _just_pressed_keys = SPDict:new()
local _down_keys = SPDict:new()
local _just_released_keys = SPDict:new()
local _textbox_focused = false
local _do_textbox_unfocus = false
local _recording_keycode_input = false
local _has_recorded_keycode_input = false
local _recorded_keycode = 0
local _custom_key_keycode = SPDict:new()
function self:cons()
userinput_service.TextBoxFocused:connect(function(textbox)
_textbox_focused = true
end)
userinput_service.TextBoxFocusReleased:connect(function(textbox)
_do_textbox_unfocus = true
end)
userinput_service.InputBegan:connect(function(input, gameProcessed)
if input.UserInputType == Enum.UserInputType.Keyboard then
if _recording_keycode_input == true then
return
end
self:input_began(input.KeyCode)
elseif input.UserInputType == Enum.UserInputType.MouseButton1 then
self:input_began(InputUtil.KEY_CLICK)
elseif input.UserInputType == Enum.UserInputType.Touch then
self:input_began(InputUtil.KEY_CLICK)
self:touch_began(input.Position.X, input.Position.Y)
end
end)
userinput_service.InputChanged:connect(function(input, gameProcessed)
if input.UserInputType == Enum.UserInputType.Touch then
self:touch_changed(input.Position.X, input.Position.Y)
end
end)
userinput_service.InputEnded:connect(function(input, gameProcessed)
if input.UserInputType == Enum.UserInputType.Keyboard then
if _recording_keycode_input == true then
_has_recorded_keycode_input = true
_recorded_keycode = input.KeyCode
return
end
self:input_ended(input.KeyCode)
elseif input.UserInputType == Enum.UserInputType.MouseButton1 then
self:input_ended(InputUtil.KEY_CLICK)
elseif input.UserInputType == Enum.UserInputType.Touch then
self:input_ended(InputUtil.KEY_CLICK)
self:touch_ended(input.Position.X, input.Position.Y)
end
end)
game.Players.LocalPlayer:GetMouse().WheelForward:connect(function()
self:input_began(InputUtil.KEY_SCROLL_UP)
end)
game.Players.LocalPlayer:GetMouse().WheelBackward:connect(function()
self:input_began(InputUtil.KEY_SCROLL_DOWN)
end)
end
local _track1_end = 0.25
local _track2_end = 0.5
local _track3_end = 0.75
function self:set_touch_track_ends(track1_end, track2_end, track3_end)
_track1_end = track1_end
_track2_end = track2_end
_track3_end = track3_end
end
function self:get_touch_track_ends() return _track1_end, _track2_end, _track3_end end
local function get_touch_keycode(x,y)
local screen_nx = x / SPUtil:screen_size().X
if screen_nx <= _track1_end then
return InputUtil.KEYCODE_TOUCH_TRACK1
elseif screen_nx <= _track2_end then
return InputUtil.KEYCODE_TOUCH_TRACK2
elseif screen_nx <= _track3_end then
return InputUtil.KEYCODE_TOUCH_TRACK3
else
return InputUtil.KEYCODE_TOUCH_TRACK4
end
end
local _active_touches = SPList:new()
local function get_nearest_touch(touch_spvec)
if _active_touches:count() == 0 then return nil end
local i_min = 1
local touch_min = _active_touches:get(1)
local val_min = touch_spvec:distance_to(touch_min)
for i=2,_active_touches:count() do
local itr = _active_touches:get(i)
local itr_dist = touch_spvec:distance_to(itr)
if itr_dist < val_min then
i_min = i
touch_min = itr
val_min = itr_dist
end
end
return touch_min, i_min
end
function self:touch_began(x,y)
local neu_touch_keycode = get_touch_keycode(x,y)
_active_touches:push_back(SPVector:new(x,y))
self:input_began(neu_touch_keycode)
end
function self:touch_changed(x,y)
local touch_moved_spvec = SPVector:new(x,y)
local nearest_touch = get_nearest_touch(touch_moved_spvec)
if nearest_touch == nil then return end
local nearest_keycode = get_touch_keycode(nearest_touch._x, nearest_touch._y)
local touch_moved_keycode = get_touch_keycode(touch_moved_spvec._x, touch_moved_spvec._y)
if nearest_keycode ~= touch_moved_keycode then
self:input_ended(nearest_keycode)
self:input_began(touch_moved_keycode)
end
nearest_touch:set(x,y)
end
function self:touch_ended(x,y)
local touch_ended_spvec = SPVector:new(x,y)
local nearest_touch, i_nearest_touch = get_nearest_touch(touch_ended_spvec)
if nearest_touch == nil then return end
_active_touches:remove_at(i_nearest_touch)
local nearest_keycode = get_touch_keycode(nearest_touch._x, nearest_touch._y)
self:input_ended(nearest_keycode)
end
function self:input_began(keycode)
_down_keys:add(keycode, true)
_just_pressed_keys:add(keycode, true)
end
function self:input_ended(keycode)
_down_keys:remove(keycode)
_just_released_keys:add(keycode, true)
end
local _last_cursor = SPVector:new(0,0)
local __get_cursor = SPVector:new(0,0)
function self:get_cursor()
local cursor = game.Players.LocalPlayer:GetMouse()
__get_cursor:set(cursor.X,cursor.Y)
return __get_cursor
end
local __get_cursor_delta = SPVector:new()
function self:get_cursor_delta()
local cursor = game.Players.LocalPlayer:GetMouse()
__get_cursor_delta:set(
cursor.X - _last_cursor._x,
cursor.Y - _last_cursor._y
)
return __get_cursor_delta
end
local _has_frame_focused_element = false
function self:set_has_frame_focused_element(val)
_has_frame_focused_element = val
end
function self:get_has_frame_focused_element()
return _has_frame_focused_element
end
function self:set_mouse_visible(val)
userinput_service.MouseIconEnabled = val
end
local _keyboard_focused_mode = false
function self:set_keyboard_focused_mode(val)
_keyboard_focused_mode = val
end
function self:post_update()
local cursor = game.Players.LocalPlayer:GetMouse()
if (SPUtil:is_mobile() == false) then
if _keyboard_focused_mode == true and (self:control_pressed(InputUtil.KEY_TRACK1) or self:control_pressed(InputUtil.KEY_TRACK2) or self:control_pressed(InputUtil.KEY_TRACK3) or self:control_pressed(InputUtil.KEY_TRACK4)) then
self:set_mouse_visible(false)
elseif cursor.X ~= _last_cursor._x or cursor.Y ~= _last_cursor._y then
self:set_mouse_visible(true)
end
end
_last_cursor:set(cursor.X,cursor.Y)
_just_pressed_keys:clear()
_just_released_keys:clear()
if _down_keys:contains(InputUtil.KEY_SCROLL_UP) then
self:input_ended(InputUtil.KEY_SCROLL_UP)
end
if _down_keys:contains(InputUtil.KEY_SCROLL_DOWN) then
self:input_ended(InputUtil.KEY_SCROLL_DOWN)
end
if _do_textbox_unfocus == true then
_do_textbox_unfocus = false
_textbox_focused = false
end
self:set_has_frame_focused_element(false)
end
local function is_control_active(control,active_dict)
if control == InputUtil.KEY_CLICK then
return active_dict:contains(InputUtil.KEY_CLICK)
end
if _textbox_focused == true then
return false
end
if control == InputUtil.KEY_TRACK1 then
if (SPUtil:is_mobile() == false) and _custom_key_keycode:contains(InputUtil.KEY_TRACK1) then
return active_dict:contains(_custom_key_keycode:get(InputUtil.KEY_TRACK1))
end
return active_dict:contains(Enum.KeyCode.A) or
active_dict:contains(Enum.KeyCode.J) or
active_dict:contains(Enum.KeyCode.One) or
active_dict:contains(Enum.KeyCode.Q) or
active_dict:contains(Enum.KeyCode.U) or
active_dict:contains(InputUtil.KEYCODE_TOUCH_TRACK1)
elseif control == InputUtil.KEY_TRACK2 then
if (SPUtil:is_mobile() == false) and _custom_key_keycode:contains(InputUtil.KEY_TRACK2) then
return active_dict:contains(_custom_key_keycode:get(InputUtil.KEY_TRACK2))
end
return active_dict:contains(Enum.KeyCode.S) or
active_dict:contains(Enum.KeyCode.K) or
active_dict:contains(Enum.KeyCode.Two) or
active_dict:contains(Enum.KeyCode.W) or
active_dict:contains(Enum.KeyCode.I) or
active_dict:contains(InputUtil.KEYCODE_TOUCH_TRACK2)
elseif control == InputUtil.KEY_TRACK3 then
if (SPUtil:is_mobile() == false) and _custom_key_keycode:contains(InputUtil.KEY_TRACK3) then
return active_dict:contains(_custom_key_keycode:get(InputUtil.KEY_TRACK3))
end
return active_dict:contains(Enum.KeyCode.D) or
active_dict:contains(Enum.KeyCode.L) or
active_dict:contains(Enum.KeyCode.Three) or
active_dict:contains(Enum.KeyCode.E) or
active_dict:contains(Enum.KeyCode.O) or
active_dict:contains(InputUtil.KEYCODE_TOUCH_TRACK3)
elseif control == InputUtil.KEY_TRACK4 then
if (SPUtil:is_mobile() == false) and _custom_key_keycode:contains(InputUtil.KEY_TRACK4) then
return active_dict:contains(_custom_key_keycode:get(InputUtil.KEY_TRACK4))
end
return active_dict:contains(Enum.KeyCode.F) or
active_dict:contains(Enum.KeyCode.Semicolon) or
active_dict:contains(Enum.KeyCode.Four) or
active_dict:contains(Enum.KeyCode.R) or
active_dict:contains(Enum.KeyCode.P) or
active_dict:contains(InputUtil.KEYCODE_TOUCH_TRACK4)
elseif control == InputUtil.KEY_POWERBAR_TRIGGER then
if _custom_key_keycode:contains(InputUtil.KEY_POWERBAR_TRIGGER) then
return active_dict:contains(_custom_key_keycode:get(InputUtil.KEY_POWERBAR_TRIGGER))
end
return active_dict:contains(Enum.KeyCode.Space)
elseif control == InputUtil.KEY_GAME_QUIT then
if _custom_key_keycode:contains(InputUtil.KEY_GAME_QUIT) then
return active_dict:contains(_custom_key_keycode:get(InputUtil.KEY_GAME_QUIT))
end
return active_dict:contains(Enum.KeyCode.Backspace)
elseif control == InputUtil.KEY_DOWN then
return active_dict:contains(Enum.KeyCode.Down)
elseif control == InputUtil.KEY_UP then
return active_dict:contains(Enum.KeyCode.Up)
elseif control == InputUtil.KEY_LEFT then
return active_dict:contains(Enum.KeyCode.Left)
elseif control == InputUtil.KEY_RIGHT then
return active_dict:contains(Enum.KeyCode.Right)
elseif control == InputUtil.KEY_A then
return active_dict:contains(Enum.KeyCode.A)
elseif control == InputUtil.KEY_B then
return active_dict:contains(Enum.KeyCode.B)
elseif control == InputUtil.KEY_MOD1 then
return active_dict:contains(Enum.KeyCode.LeftShift)
elseif control == InputUtil.KEY_MENU_OPEN then
return active_dict:contains(Enum.KeyCode.Return)
elseif control == InputUtil.KEY_MENU_ENTER then
return false
--return (active_dict:contains(Enum.KeyCode.Return) and _textbox_focused == false)
elseif control == InputUtil.KEY_MENU_BACK then
return active_dict:contains(Enum.KeyCode.Backspace)
elseif control == InputUtil.KEY_MENU_MATCHMAKING_CHAT_FOCUS then
if _custom_key_keycode:contains(InputUtil.KEY_MENU_MATCHMAKING_CHAT_FOCUS) then
return active_dict:contains(_custom_key_keycode:get(InputUtil.KEY_MENU_MATCHMAKING_CHAT_FOCUS)) and (_textbox_focused == false)
end
return active_dict:contains(Enum.KeyCode.Period) and (_textbox_focused == false)
elseif control == InputUtil.KEY_CHAT_WINDOW_FOCUS then
if _custom_key_keycode:contains(InputUtil.KEY_CHAT_WINDOW_FOCUS) then
return active_dict:contains(_custom_key_keycode:get(InputUtil.KEY_CHAT_WINDOW_FOCUS)) and (_textbox_focused == false)
end
return active_dict:contains(Enum.KeyCode.Slash) and (_textbox_focused == false)
elseif control == InputUtil.KEY_MENU_SPUITEXTINPUT_ESC then
return active_dict:contains(Enum.KeyCode.Escape)
elseif control == InputUtil.KEY_SCROLL_UP then
return active_dict:contains(InputUtil.KEY_SCROLL_UP)
elseif control == InputUtil.KEY_SCROLL_DOWN then
return active_dict:contains(InputUtil.KEY_SCROLL_DOWN)
elseif control == InputUtil.KEY_DEBUG_1 then
return active_dict:contains(Enum.KeyCode.PageUp)
elseif control == InputUtil.KEY_DEBUG_2 then
return active_dict:contains(Enum.KeyCode.PageDown)
elseif control == InputUtil.KEY_DEBUG_3 then
return active_dict:contains(Enum.KeyCode.Home)
elseif control == InputUtil.KEY_DEBUG_4 then
return active_dict:contains(Enum.KeyCode.End)
elseif control == InputUtil.KEYCODE_TOUCH_TRACK1 then
return _down_keys:contains(InputUtil.KEYCODE_TOUCH_TRACK1)
elseif control == InputUtil.KEYCODE_TOUCH_TRACK2 then
return _down_keys:contains(InputUtil.KEYCODE_TOUCH_TRACK2)
elseif control == InputUtil.KEYCODE_TOUCH_TRACK3 then
return _down_keys:contains(InputUtil.KEYCODE_TOUCH_TRACK3)
elseif control == InputUtil.KEYCODE_TOUCH_TRACK4 then
return _down_keys:contains(InputUtil.KEYCODE_TOUCH_TRACK4)
else
error("INPUTKEY NOT FOUND ",control)
return false
end
end
function self:control_just_pressed(control)
return is_control_active(control,_just_pressed_keys)
end
function self:control_pressed(control)
return is_control_active(control,_down_keys)
end
function self:control_just_released(control)
return is_control_active(control,_just_released_keys)
end
function self:clear_just_pressed_keys()
_just_pressed_keys:clear()
end
function self:clear_just_released_keys()
_just_released_keys:clear()
end
--------- Keycode Record
function self:record_next_keycode_input()
_recording_keycode_input = true
_has_recorded_keycode_input = false
end
function self:has_recorded_keycode_input()
return _has_recorded_keycode_input
end
function self:cancel_record_next_keycode_input()
_recording_keycode_input = false
end
function self:get_recorded_keycode()
return _recorded_keycode
end
--------- Custom controls
function self:reset_to_default_controls()
_custom_key_keycode:clear()
end
function self:set_custom_key_keycode(key, keycode)
_custom_key_keycode:add(key, keycode)
end
function self:remove_custom_key(key)
_custom_key_keycode:remove(key)
end
function self:get_custom_key_keycode(key)
return _custom_key_keycode:get(key)
end
function self:get_key_display_str(key)
if _custom_key_keycode:contains(key) then
return _custom_key_keycode:get(key).Name
end
if key == InputUtil.KEY_MENU_MATCHMAKING_CHAT_FOCUS then
return "."
elseif key == InputUtil.KEY_CHAT_WINDOW_FOCUS then
return "/"
elseif key == InputUtil.KEY_TRACK1 then
return "A/J/Q/U/1"
elseif key == InputUtil.KEY_TRACK2 then
return "S/K/W/I/2"
elseif key == InputUtil.KEY_TRACK3 then
return "D/L/E/O/3"
elseif key == InputUtil.KEY_TRACK4 then
return "F/;/R/P/4"
elseif key == InputUtil.KEY_POWERBAR_TRIGGER then
return "Space"
else
return string.format("??? (%d)",tostring(key))
end
end
self:cons()
return self
end
local _keycode_enum_to_value = SPDict:new()
local _value_to_keycode_enum = SPDict:new()
for _,k in pairs(Enum.KeyCode:GetEnumItems()) do
local v = k.Value
_keycode_enum_to_value:add(k,v)
_value_to_keycode_enum:add(v,k)
end
function InputUtil:keycode_enum_to_value(k) return _keycode_enum_to_value:get(k) end
function InputUtil:value_to_keycode_enum(v) return _value_to_keycode_enum:get(v) end
return InputUtil
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment