Non-accurate sliders within a surfaceGUI

Hi all.

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.

For context, here’s the UI in question.

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?

Thank you in advance!

2 Likes

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
1 Like

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…

Let me make a demo place for you! It won’t take much time. Give me about 15 minutes!

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)

1 Like

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!

1 Like

Any time dude, Keep up the good Work!

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.