I’ve been having a bit of a problem trying to get sliders working in surfaceGUI’s. Most cases, sliders are used on normal GUI, meaning getting mouse position is just about perfect for it. But that isn’t the case for surfaceGUI (or billboard, but this post is specifically about surfaceGUI)
The problem is, the traditional method isn’t going to take into account the positioning of your mouse relative to the space that you’re actually moused/dragging over in the surfaceGUI. I’ve seen a few people suggest raycasting, and that’s a method I would like to try to fix this problem, but I’m honestly not quite sure where to begin in that regard.
I’d post an example script, but seeing as I’ll need to move completely to raycasting in order to get any degree of accuracy with this, it’ll require me to up-end my entire slider script anyways.
Can anyone give any advice, or any useful pointers on how to achieve the desired effect? And is there perhaps an easier way I’ve been missing?
You can Convert your Mouse Position Into a 2D Position from 0 to 1
Since you have
StartX
StartY
EndX and EndY
And you have Mouse.Hit
You Can Calculate The Mouse Position Based On Theese Information And Use The Classic Method
Example For X Axis:
local PartSize = Vector3.new(10, 10, 1)
local StartX = 10 - (PartSize.X/2) -- This Is Part Start Position X
local EndX= 10 + (PartSize.X/2) -- This Is Part Start Position X
local MousePosition = Player:GetMouse().Hit.Position -- Mouse Position
local Distance = MousePosition - StartX -- Distance Between StartX And Mouse Position
local UIScaleXPos = (StartX + Distance) / EndX
Ah…! That seems to be on the right track! Thank you for the reply. though I’m not 100% sure how I’m meant to work with it exactly with the given explanation. (Not your fault, I’m just a bit of a slow learner…!)
That being said, this is the updated script I have thus far.
local UIS = game:GetService("UserInputService")
local sliderButton = script.Parent
local sliderFrame = sliderButton.Parent
local drag = false
sliderButton.MouseButton1Down:Connect(function()
drag = true
end)
UIS.InputEnded:Connect(function(input)
if input.UserInputType == Enum.UserInputType.MouseButton1 then
drag = false
end
end)
UIS.InputChanged:Connect(function(input)
if input.UserInputType == Enum.UserInputType.MouseMovement then
if drag == true then
local PartSize = script.Parent:FindFirstAncestor("Screen test").Size
local StartX = 10 - (PartSize.X/2) -- This Is Part Start Position X
local EndX= 10 + (PartSize.X/2) -- This Is Part End Position X
local MousePosition = game.Players.LocalPlayer:GetMouse().Hit.Position -- Mouse Position
local Distance = MousePosition.X - StartX -- Distance Between StartX And Mouse Position
local UIScaleXPos = (StartX + Distance) / EndX
local percentage = math.clamp(UIScaleXPos,0,1)
end
end
end)
ideally, I’d like to clamp the value between 0 and 1 for simplification sake in future, hense the “percentage” variable. but, for some reason the value of UIScalePos is always the mouse’s X position of worldSpace in the example I gave here. Would I need to negate the parts current X position with the output of UIScaleXPos…? Or is there something else I’m missing?
Plus that sounds like a veeery janky way of getting around it…
Heres a Demo If The Exact Calculations. Your Welcome. (It’s Laggy Because I’m Using Print in Render Stepped [You won’t have to use print in real game]) Mouse2DScale.rbxl (53.6 KB)
Thank you so much…! The place helped a heck of a lot to wrap my head around it.
This was a nightmare to find online, so for anyone else searching this in the future who may be struggling with this, I urge you to experiment around with the place Hot_Coder made above!