You can write your topic however you want, but you need to answer these questions:
- What do you want to achieve? Keep it simple and clear!
I’m trying to make a Map GUI that allows you to scale its contents up and down and horizontally scroll by using a combination of UserInputServices’ PointerAction Method (basically an inputBegan method specifically for mouse wheels and trackpads) and isKeyDown.
The TL;DR of how the code works is that it activates a PointerAction when the mouse enters the map frame, then checks what keys are being held down when they scroll and perform their corresponding action. If you want the actual code line-for-line or if you want a more lengthy explanation, the code breakdown is below:
Code Breakdown
First, let me give you the global variables and explorer path of everything so you can reference them for context:
Variables
local resizeFrame = script.Parent
-- ^^ The content frame that all the map's content is stored in (for proper scaling)
local mapFrame = resizeFrame.Parent
-- ^^ The ScrollingFrame that holds everything map-related
local inputService = game:GetService("UserInputService")
-- ^^ UserInputService for PointedAction and isKeyDown
local scrollConnect
-- ^^ Houses the event for a mouse entering the map so it can be disconnected later
local scrollSensitivity = 10
-- ^^ a multiplier applied to the detected scroll wheel/pan/pinch so it doesn't ...
--... take ages to pan/scale the map
Now, onto the explanation:
This is pretty simple, so this won’t take long. First, I prepare simple logic that initiates the scaling/panning logic (transformFrame
) when the user’s mouse enters the map GUI, then disconnects everything once it leaves. Not sure if I have to do this, but it’s better to be safe than sorry
resizeFrame.MouseEnter:Connect(function()
scrollConnect = inputService.PointerAction:Connect(transformFrame)
end)
resizeFrame.MouseLeave:Connect(function()
scrollConnect:Disconnect()
end)
Inside transformFrame,
it starts by using :isKeyDown
to check if the control or shift keys were pressed when it was activated. The zoom feature is bonded to control, while the horizontal scroll is bonded to shift.
local function transformFrame(wheel:number, pan:Vector2, pinch:number, isGUI:boolean)
local isZooming = inputService:IsKeyDown(Enum.KeyCode.RightShift) or inputService:IsKeyDown(Enum.KeyCode.LeftShift)
local isPanning = inputService:IsKeyDown(Enum.KeyCode.RightControl) or inputService:IsKeyDown(Enum.KeyCode.LeftControl)
Then, it performs a series of checks to decide what it will do next:
- If there’s no pinch, pan, and neither the zoom or pan keys are being held down, it does nothing because ScrollingFrames can already handle vertical scrolling by its lonesome.
if not isPanning and not isZooming or pan.X ~= 0 or pan.Y ~= 0 then
warn("Vertically scrolling!")
return
end
- At this point, we’ve already verified that the user is trying to horizontally scroll, so I have to disable manual scrolling so roblox doesn’t automatically vertically scroll for me
mapFrame.ScrollingEnabled = false
- There also has to be another check to make sure that the zoom and pan keys aren’t being held at the same time
if isPanning and isZooming then
warn("You can't pan and zoom at the same time!")
mapFrame.ScrollingEnabled = true
return
- Finally, it does the logic on whether to zoom or scroll:
- If the user is holding ctrl or is actively pinching the mapGUI, the map zooms out
elseif isZooming or pinch ~= 0 then
scaleMapFrame(wheel, pinch)
- If the user is holding shift or is actively horizontally panning the screen, then the map horizontally pans
elseif isPanning or pan.X ~= 0 then
if pan.X ~= 0 then
return horizontalMapFrameMove(pan.X)
end
horizontalMapFrameMove(wheel)
end
- Then when everything’s said and done, scrolling gets reenabled
mapFrame.ScrollingEnabled = true
And that’s it! I’m sure there are more efficient ways of doing things, but that’s just how I chose to do it. I’ll probably improve the logic later because even as I write this, I see a few parts that could cause bugs later down the line.
-
What is the issue? Include screenshots / videos if possible!
Basically, theisKeyDown
methods to check if a certain key is being pressed always returnsfalse
regardless of if its being held down or not. No idea what’s happening because the PointerAction does get triggered and the function inside of it does indeed run, but no matter what happens,isKeyDown
always returnsfalse
no matter what. Below is proof of this weird bug happening:
Video of Issue in Action
-
What solutions have you tried so far? Did you look for solutions on the Developer Hub?
I could disregardisKeyDown
and manually useinputBegan
events to track if the key is being held or not, but I’m hoping that I don’t have to do anything like that and can use the Roblox tools bestowed upon me by the great devs in the sky.
If anyone could help me with this, I’d be static. So far, I’ve had a 0% response rate on any of the 3 topics I’ve opened, so it would make my day if anyone even attempted to help me instead of clicking off. But regardless of if you help me or not, thanks for reading this all the way through
Updates/Fix Attempts:
- Moving
isKeyDown
to be inside of a heartbeat loop, in case the PointerAction event didn’t trigger them frequently enough to see the key presses
Changes made to the code
- Added 4 new global variables:
- RunService
- isZooming (the zoom key’s
isKeyDown
) - isPanning (the horizontal pan’s
isKeyDown
) - heldKeyHeartbeat (the HeartBeat connect used to disconnect the service when not hovering over the map GUI (for optimization purposes))
local resizeFrame = script.Parent
local mapFrame = resizeFrame.Parent
local inputService = game:GetService("UserInputService")
local runService = game:GetService("RunService") <-- new!
local scrollSensitivity = 10
local scrollConnect
local heldKeyHeartbeat <-- new!
local isZooming = nil <-- new!
local isPanning = nil <-- new!
- Changed the resizeFrame’s
MouseEnter
connect to also start a heartbeat connect that constantly checks for the shift and control keys
resizeFrame.MouseEnter:Connect(function()
scrollConnect = inputService.PointerAction:Connect(transformFrame)
-- vvv new stuff below... vvv
heldKeyHeartbeat = runService.Heartbeat:Connect(function()
isZooming = inputService:IsKeyDown(Enum.KeyCode.RightShift) or inputService:IsKeyDown(Enum.KeyCode.LeftShift)
isPanning = inputService:IsKeyDown(Enum.KeyCode.RightControl) or inputService:IsKeyDown(Enum.KeyCode.LeftControl)
end)
end)
- Changed the resizeFrame’s
MouseLeave
connect to also disconnect the heartbeat connect so it doesn’t slow down the game while it’s not being used
resizeFrame.MouseLeave:Connect(function()
scrollConnect:Disconnect()
heldKeyHeartbeat:Disconnect() <-- new!
end)
Results Showcase (failed)
I ended up having to reinstall studio, but at least everything works now! This is 14 days later because I forgot about this thread. Sorry…
Edit Log
Edit #1: 3:56AM MST, 7/16/24
- Added “Updates/Fix Attempts” Page
- Added first fix attempt
- Fixed typo in “What is the issue?”
- Get rid of the
...
when introducing the code breakdown’stransformFrame
function (sorry for the confusion!)