Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- function aConfiguration()
- return {
- -- Raycast distance for the CFrame and Target properties
- RaycastDistance = 1000;
- -- Maximum number of seconds for a mouse button to be down for the click event to be called
- ClickThreshold = 0.5;
- -- Whether touch input is mapped to the first (left) mouse button
- DetectTouchAsButton1 = true;
- -- Whether the mouse has target functionality (Target and TargetFilter)
- TargetEnabled = true;
- -- Update properties with RunService and not mouse movemenet
- -- Less efficient than updating with mouse movement, but will update properties even if mouse hasn't been moved
- ConstantlyUpdatingProperties = true;
- }
- end
- function aInput()
- local CONFIG = aConfiguration()
- local UIT_TOUCH = Enum.UserInputType.Touch
- local UIT_BUTTON1 = Enum.UserInputType.MouseButton1
- local UserInputService = game:GetService("UserInputService")
- local RenderStepped = game:GetService("RunService").RenderStepped
- local boundActions = {}
- local boundBinaryActions = {}
- local boundChangeActions = {}
- local boundFrames = {}
- local connectionBegin, connectionEnd, connectionChanged, connectionFrame
- local callbackBegan, callbackEnded, callbackChanged, callbackFrame do
- callbackBegan = function(inputObject)
- local input = inputObject.UserInputType
- if (CONFIG.DetectTouchAsButton1 and input == UIT_TOUCH) then
- input = UIT_BUTTON1
- end
- local inputCallbacks = boundActions[input]
- if inputCallbacks then
- for index = 1, #inputCallbacks do
- inputCallbacks[index]()
- end
- end
- local inputBinaryCallbacks = boundBinaryActions[input]
- if inputBinaryCallbacks then
- for index = 1, #inputBinaryCallbacks do
- inputBinaryCallbacks[index](true)
- end
- end
- end
- callbackEnded = function(inputObject)
- local input = inputObject.UserInputType
- if (CONFIG.DetectTouchAsButton1 and input == UIT_TOUCH) then
- input = UIT_BUTTON1
- end
- local inputBinaryCallbacks = boundBinaryActions[input]
- if inputBinaryCallbacks then
- for index = 1, #inputBinaryCallbacks do
- inputBinaryCallbacks[index](false)
- end
- end
- end
- callbackChanged = function(inputObject)
- local input = inputObject.UserInputType
- local inputCallbacks = boundChangeActions[input]
- if inputCallbacks then
- for index = 1, #inputCallbacks do
- inputCallbacks[index](inputObject)
- end
- end
- end
- callbackFrame = function()
- for index = 1, #boundFrames do
- boundFrames[index](UserInputService)
- end
- end
- end
- local Input = {} do
- Input.bindAction = function(action, callback)
- if not boundActions[action] then boundActions[action] = {} end
- table.insert(boundActions[action], callback)
- end
- Input.bindActionBinary = function(action, callback)
- if not boundBinaryActions[action] then boundBinaryActions[action] = {} end
- table.insert(boundBinaryActions[action], callback)
- end
- Input.bindActionChange = function(action, callback)
- if not boundChangeActions[action] then boundChangeActions[action] = {} end
- table.insert(boundChangeActions[action], callback)
- end
- Input.bindToFrame = function(callback)
- table.insert(boundFrames, callback)
- end
- Input.disable = function()
- connectionBegan:Disconnect()
- connectionEnded:Disconnect()
- connectionChanged:Disconnect()
- connectionFrame:Disconnect()
- end
- Input.enable = function()
- connectionBegan = UserInputService.InputBegan:Connect(callbackBegan)
- connectionEnded = UserInputService.InputEnded:Connect(callbackEnded)
- connectionChanged = UserInputService.InputChanged:Connect(callbackChanged)
- connectionFrame = RenderStepped:Connect(callbackFrame)
- end
- Input.enable()
- end
- return Input
- end
- function aMouseRay()
- local CONFIG = aConfiguration()
- local MouseRay = {} do
- local Ray = Ray.new
- local CFrame = CFrame.new
- local Camera = workspace.CurrentCamera
- local cache = {nil, CFrame()}
- MouseRay.new = function(position, targetFilter)
- local newRay = Camera:ScreenPointToRay(position.X, position.Y) do
- newRay = Ray(newRay.Origin, newRay.Direction * CONFIG.RaycastDistance)
- end
- cache = {workspace:FindPartOnRayWithIgnoreList(newRay, targetFilter)}
- cache[3] = newRay.Unit.Direction
- end
- MouseRay.getCFrame = function()
- return CFrame(cache[2], cache[3])
- end
- MouseRay.getTarget = function()
- return cache[1]
- end
- end
- return MouseRay
- end
- function aRbxMouseButton()
- local CONFIG = aConfiguration()
- local Input = aInput()
- local buttons = {}
- local makeNewButton = function(buttonId)
- local buttonInputType = Enum.UserInputType["MouseButton" ..buttonId]
- local properties = {} do
- properties.ButtonId = buttonId
- properties.ButtonName =
- (buttonId == 1 and "Left") or
- (buttonId == 2 and "Right") or
- (buttonId == 3 and "Middle")
- properties.IsDown = false
- end
- local signals = {} do
- signals.Down = Instance.new("BindableEvent")
- signals.Up = Instance.new("BindableEvent")
- Input.bindActionBinary(buttonInputType, function(isBegin)
- if isBegin and not properties.IsDown then
- properties.IsDown = true
- signals.Down:Fire()
- elseif not isBegin and properties.IsDown then
- properties.IsDown = false
- signals.Up:Fire()
- end
- end)
- signals.Click = Instance.new("BindableEvent") do
- local wentDownAt
- signals.Down.Event:Connect(function()
- wentDownAt = tick()
- end)
- signals.Up.Event:Connect(function()
- local timeSpentDown = tick() - wentDownAt
- if timeSpentDown > CONFIG.ClickThreshold then return end
- signals.Click:Fire(timeSpentDown)
- end)
- end
- end
- local methods = {} do
- methods.ForceDown = function()
- if properties.IsDown then return end
- properties.IsDown = true
- signals.Down:Fire()
- end
- methods.ForceUp = function()
- if not properties.IsDown then return end
- properties.IsDown = false
- signals.Up:Fire()
- end
- end
- local newButton = {} do
- setmetatable(newButton, {
- __index = function(self, index)
- local property = properties[index]
- if property then return property end
- local signal = signals[index]
- if signal then return signal.Event end
- local method = methods[index]
- if method then return method end
- error(tostring(index).. " is not a valid member of RbxMouseButton")
- end,
- __newindex = function() end
- })
- end
- return newButton
- end
- local RbxMouseButtonContainer = {} do
- setmetatable(RbxMouseButtonContainer, {
- __index = function(self, index)
- local buttonId =
- ((index == 1 or index == "Left") and 1) or
- ((index == 2 or index == "Right") and 2) or
- ((index == 3 or index == "Middle") and 3)
- if not buttonId then error(tostring(index).. " is not a valid mouse button") end
- if not buttons[buttonId] then
- buttons[buttonId] = makeNewButton(buttonId)
- end
- return buttons[buttonId]
- end,
- __newindex = function() end
- })
- end
- return RbxMouseButtonContainer
- end
- function aRbxMouseIcon()
- local methods = {} do
- local UserInputService = game:GetService("UserInputService")
- local RenderStepped = game:GetService("RunService").RenderStepped
- local Mouse = game:GetService("Players").LocalPlayer:GetMouse()
- local currentMouseIcon = Mouse.Icon
- methods.Hide = function()
- UserInputService.MouseIconEnabled = false
- end
- methods.Show = function()
- UserInputService.MouseIconEnabled = true
- end
- methods.Set = function(id)
- local assetId =
- (typeof(id) == "number" and "rbxassetid://" ..id) or
- (typeof(id) == "string" and id) or
- (not id and "") or
- Mouse.Icon
- Mouse.Icon = assetId
- end
- methods.Get = function()
- return Mouse.Icon
- end
- end
- local RbxMouseIcon = {} do
- setmetatable(RbxMouseIcon, {
- __index = function(self, index)
- local method = methods[index]
- if method then return method end
- error(tostring(index).. " is not a valid member of RbxMouseIcon")
- end,
- __newindex = function() end
- })
- end
- return RbxMouseIcon
- end
- function aRbxTargetFilter()
- local methods = {} do
- local filterTable = {}
- methods.Set = function(self, object)
- if typeof(object) == "table" then
- filterTable = object
- else
- filterTable = {object}
- end
- end
- methods.Get = function()
- return filterTable
- end
- methods.Add = function(self, object)
- for index = 1, #filterTable do
- if object == filterTable[index] then
- return
- end
- end
- table.insert(filterTable, object)
- end
- methods.Remove = function(self, object)
- for index = 1, #filterTable do
- if object == filterTable[index] then
- table.remove(filterTable, index)
- break
- end
- end
- end
- end
- local RbxTargetFilter = {} do
- setmetatable(RbxTargetFilter, {
- __index = function(self, index)
- local method = methods[index]
- if method then return method end
- error(tostring(index).. " is not a valid member of RbxTargetFilter")
- end,
- __newindex = function() end
- })
- end
- return RbxTargetFilter
- end
- local CONFIG = aConfiguration()
- local UIT_MOUSE_MOVEMENT = Enum.UserInputType.MouseMovement
- local Input = aInput()
- local children = {} do
- children.Button = aRbxMouseButton()
- children.Icon = aRbxMouseIcon()
- if CONFIG.TargetEnabled then
- children.TargetFilter = aRbxTargetFilter()
- end
- end
- local properties = {} do
- local MouseRay = aMouseRay()
- properties.Position = Vector2.new()
- properties.CFrame = CFrame.new()
- if not CONFIG.ConstantlyUpdatingProperties then
- Input.bindActionChange(UIT_MOUSE_MOVEMENT, function(inputObject)
- properties.Position = Vector2.new(inputObject.Position.X, inputObject.Position.Y)
- MouseRay.new(properties.Position, children.TargetFilter:Get())
- properties.CFrame = MouseRay.getCFrame()
- end)
- else
- Input.bindToFrame(function(UserInputService)
- local mousePosition = UserInputService:GetMouseLocation()
- properties.Position = mousePosition
- MouseRay.new(mousePosition, children.TargetFilter:Get())
- properties.CFrame = MouseRay.getCFrame()
- end)
- end
- if CONFIG.TargetEnabled then
- properties.Target = nil
- local updateTarget = function()
- properties.Target = MouseRay.getTarget()
- end
- if not CONFIG.ConstantlyUpdatingProperties then
- Input.bindActionChange(UIT_MOUSE_MOVEMENT, updateTarget)
- else
- Input.bindToFrame(updateTarget)
- end
- end
- end
- local signals = {} do
- signals.Move = Instance.new("BindableEvent")
- Input.bindActionChange(UIT_MOUSE_MOVEMENT, function()
- signals.Move:Fire(properties.Position)
- end)
- end
- local methods = {} do
- methods.Enable = function(self)
- Input.enable()
- end
- methods.Disable = function(self)
- Input.disable()
- end
- end
- local RbxMouse = {} do
- local getMember = function(self, index)
- local child = children[index]
- if child then return child end
- local property = properties[index]
- if property then return property end
- local signal = signals[index]
- if signal then return signal.Event end
- local method = methods[index]
- if method then return method end
- end
- setmetatable(RbxMouse, {
- __index = function(self, index)
- local member = getMember(self, index)
- if member then return member end
- if CONFIG.TargetEnabled and index == "Target" then return nil end
- error(tostring(index).. " is not a valid member of RbxMouse")
- end,
- __newindex = function() end
- })
- end
- return RbxMouse
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement