Using a 3-lined RGB slider, doesn't work on phones

Pretty much, I am trying to achieve a mobile-supported RGB slider. As I didn’t know how to make sliders, I used an open-sourced script. For the dragger, I am using a text button.

image

Regardless of it working with a studio emulator, it is a totally different situation ingame.
The output says absolutely nothing, hence why I’m asking for help on the dev forum.

Code of the circular dragger

script.Parent.Changed:connect(function()
local x = script.Parent.Position.X.Offset
local y = 0

if x > 100 then
	x = 100
end

if x < 0 then
	x = 0
end

local NewPos = UDim2.new(0,x,0,y)

if script.Parent.Position ~= NewPos then
	script.Parent.Position = NewPos
end

end)

Code of the self-updating box on the right side of the image

local r,g,b

for i,v in pairs(script.Parent.Parent:GetChildren()) do
if v.Name == “ColorSlider” then
local s = v:WaitForChild(“Slider”)

	s.Changed:connect(function()
		local OriginalColor = v.BackgroundColor3
		local Percentage = s.Position.X.Offset/100
		
		if OriginalColor.r == 1 then
			r = Percentage*255
			script.Parent.Parent.RLabel.Value = r
		end
		
		if OriginalColor.g == 1 then
			g = Percentage*255
			script.Parent.Parent.GLabel.Value = g
		end
		
		if OriginalColor.b == 1 then
			b = Percentage*255
			script.Parent.Parent.BLabel.Value = b
		end
		
		script.Parent.BackgroundColor3 = Color3.fromRGB(r,g,b)
	end)
end

end

Any help is appreciated. Thanks! :smile:

2 Likes

:connect() is deprecated. Use :Connect() instead.

I don’t see any code that’s listening for activation, mind to show more of your script?

Unfortunately, those two scripts are the entire code. As I didn’t know how to make a slider, I used an open-source version to give it a try.
It does work in studio by using a phone emulator tho, but having no activation in it might be the case why it isn’t compatible with mobile.

Could you perhaps give me a tip on how to potentially fix it? I’m not experienced with scripting sliders, but you probably are. :smile:

It’s absolutely fine, someone else most likely will notice the post.
Thanks tho!

Advice: you can use

x = math.clamp(x, 0, 100);

instead of

if x > 100 then
	x = 100
end

if x < 0 then
	x = 0
end

It makes the code look neater :relaxed:

4 Likes

That definitely reduces the code. Thanks!

Anyone else have any ideas how to fix this issue tho?

As Kacper said, you should use the TextButton.Activated event.

It fires when you hold the MouseButton1 down or touch the button and release it.

A simple fix that might work is to simply replace the .Changed with .Activated.

1 Like

I have just made a custom RGB dragger API with simple OOP, and the result is quite satisfying!
Video: https://streamable.com/j636d

GUI Structure: StructureOfRGBDragger

Here’s the code:
LocalScript:

local ModuleScript = require(script:WaitForChild("RGBDraggerAPI"))

ModuleScript:MountDragger(script.Parent:WaitForChild("Red_Hitbox").Dragger_Bar, "red")
ModuleScript:MountDragger(script.Parent:WaitForChild("Green_Hitbox").Dragger_Bar, "green")
ModuleScript:MountDragger(script.Parent:WaitForChild("Blue_Hitbox").Dragger_Bar, "blue")

Module:

local module = {}

if game:GetService("RunService"):IsServer() then warn("RGBDraggerAPI can only be ran by a LocalScript.") return end

local MountedDraggers = {}

--module.__index = module

local Player = game.Players.LocalPlayer

local UIS = game:GetService("UserInputService")

function module:MountDragger(Dragger, Color)
    if not Dragger or not Color then return end
    if string.lower(Color) ~= "red" and string.lower(Color) ~= "green" and string.lower(Color) ~= "blue" then return end
    if MountedDraggers[string.lower(Color)] ~= nil then return end
    if not Dragger:FindFirstChild("Dragger") then return end
    if not Dragger.Dragger:IsA("TextButton") then return end
    --Variables
    local PlayerMouse = Player:GetMouse()
    
    local Button = Dragger.Dragger
    local ColorBox = Dragger.Parent.Parent.Color_Box
    
    local Hovering = false
    local Holding = false
    
    --Basic OOP setup
    local self = {}
    --setmetatable(self, module)
    
    self.Percentage = 0
    self.ColorValue = 0
    
    local Phantom = Dragger.Dragger:Clone()
    Phantom.Visible = true
    Phantom.Parent = Dragger
    Phantom.Position = UDim2.new(0, Dragger.AbsoluteSize.X - Dragger.Dragger.AbsoluteSize.X, Dragger.Dragger.Position.Y.Scale, Dragger.Dragger.Position.Y.Offset)
    
    self.MaxPixel = Phantom.Position.X.Offset
    
    game:GetService("Debris"):AddItem(Phantom, 1) -- Don't wanna mess anything up lol

    --Register
    MountedDraggers[string.lower(Color)] = self
    
    --Functions
    local function ConvertPercentageIntoRGB(Percentage)
        if not Percentage then return end
        if Percentage > 100 or Percentage < 0 then return end
        return (255 * (Percentage / 100)) -- Converts percentage into RGB friendly value
    end

    local function CalculatePercentage(Instance)
        if not Instance then return end
        return math.ceil((Instance.Position.X.Offset * 100) / self.MaxPixel)
    end

    local function TurnIntsIntoRGB(R, G, B)
        if not R or not G or not B then return end
        return Color3.fromRGB(R, G, B)
    end

    --Events
    if not UIS.TouchEnabled and UIS.KeyboardEnabled and UIS.MouseEnabled then
        
        print("User is using a PC!")
        
        self.DeviceMode = "PC"    
    
        self.MouseEnterConnection = Dragger.Parent.MouseEnter:Connect(function()
            Hovering = true
        end)

        self.MouseLeaveConnection = Dragger.Parent.MouseLeave:Connect(function()
            Hovering = false
        end)

        self.ButtonDownConnection = PlayerMouse.Button1Down:Connect(function()
            Holding = true
        end)

        self.ButtonUpConnection = PlayerMouse.Button1Up:Connect(function()
            Holding = false
        end)
    
        self.MouseMoveConnection = PlayerMouse.Move:Connect(function()
            local MouseXPixelPos = PlayerMouse.X
            local ActualXPixelPos = PlayerMouse.X - Dragger.AbsolutePosition.X
            if Hovering and Holding then
	            if ActualXPixelPos > self.MaxPixel then ActualXPixelPos = self.MaxPixel end
	            if ActualXPixelPos < 0 then ActualXPixelPos = 0 end
	            Button.Position = UDim2.new(0, ActualXPixelPos, Button.Position.Y.Scale, Button.Position.Y.Offset)
	            self.Percentage = CalculatePercentage(Button)
	            self.ColorValue = ConvertPercentageIntoRGB(self.Percentage)
	            MountedDraggers[string.lower(Color)] = self
	            if self.ColorValue and MountedDraggers["red"] and MountedDraggers["green"] and MountedDraggers["blue"] then
		            ColorBox.BackgroundColor3 = TurnIntsIntoRGB(MountedDraggers["red"].ColorValue, MountedDraggers["green"].ColorValue, MountedDraggers["blue"].ColorValue) or Color3.fromRGB(0, 0, 0)
	            end
            end
        end)
    else
        print("User is using a mobile device!")
        
        self.DeviceMode = "Mobile"
        --Code for mobile (I have no idea of what to do here!)
        self.ButtonActivateConnection = Button.Activated:Connect(function()
	        
        end)
    end

    return self
end


--Additional functions for Lua GC and people who don't like UntrackedMemory
function module:UnmountDragger(Color)
    if MountedDraggers[string.lower(Color)] then
	    if MountedDraggers[string.lower(Color)].DeviceMode == "PC" then
	        MountedDraggers[string.lower(Color)].MouseEnterConnection:Disconnect()
	        MountedDraggers[string.lower(Color)].MouseLeaveConnection:Disconnect()
	        MountedDraggers[string.lower(Color)].ButtonDownConnection:Disconnect()
	        MountedDraggers[string.lower(Color)].ButtonUpConnection:Disconnect()
	        MountedDraggers[string.lower(Color)].MouseMoveConnection:Disconnect()
	    elseif MountedDraggers[string.lower(Color)].DeviceMode == "Mobile" then
	    	MountedDraggers[string.lower(Color)].ButtonActivateConnection:Disconnect()
	    	--More to come
	    end
    	MountedDraggers[string.lower(Color)] = nil
    end
end

function module:UnmountAll()
    for i,v in pairs(MountedDraggers) do
	    if v.DeviceMode == "PC" then
	        v.MouseEnterConnection:Disconnect()
	        v.MouseLeaveConnection:Disconnect()
	        v.ButtonDownConnection:Disconnect()
	        v.ButtonUpConnection:Disconnect()
	        v.MouseMoveConnection:Disconnect()
	    elseif v.DeviceMode == "Mobile" then
		    v.ButtonActivateConnection:Disconnect()
		    --More to come
    	end
    end
    MountedDraggers = {}
end

return module

However, I have absolutely no idea how to make it compatible for mobile users. Can someone else help me do that? Thanks.

Edit: Added in GUI structure and minor code changes.

3 Likes

Perhaps try using TouchStarted and TouchEnded.

Is there an efficient way of checking if the person is using a mobile device?

1 Like

I don’t see how pointing them to the UserInputService page is helpful considering the problem isn’t necessarily something that can just be searched. It’s a compatibility issue. As far as I can see in the OP though, I’m not seeing any activation code. I’m assuming the Draggable property is being used here?

1 Like

I am truly sorry for sending that, I hadn’t examined the question asked enough and I was mistaken, I really apologize.

2 Likes

I’m pretty sure GUI MouseEnter() and MouseLeave() don’t actually fire on mobile devices, which is why @LadyCelastia’s code won’t work on them. I don’t think Roblox added any replacements, so you will need to get a bit hacky to achieve what you want.

After doing some searching, I found the quite verbose GetGuiObjectsAtPosition() function. You could probably wrap that into a loop and set Hovering to true if the slider is at the mouse’s position (this should work on touch devices too).

1 Like