What I want to do is for the GUI to know which color it’s touching, like in this image.
Heya @pageotkillian1! How are you doing?
To understand properly, you want to create a GUI that detects what color the player is touching, right?
If so, another question: Does the player need to touch a part so the GUI can detect and print the color value?
Is that even Roblox? How are you using Block Code?
What I meant was that if a Gui touches a specific color of another Gui
it’s not from roblox, it’s from scratch
To Detect the GUIs the gui is touching, you can first get the corners of the ui ( ui.Rotation must be 0, ui must be GuiObject, you can’t detect touch of an image ( image label ) )
local function getCorners(ui:GuiObject)
local absp = ui.AbsolutePosition
local abss = ui.AbsoluteSize
local c1 = absp + (Vector2.new(abss.X,abss.Y)/2) -- bottom right
local c2 = absp + (Vector2.new(abss.X, -abss.Y)/2) -- top right
local c3 = absp + (Vector2.new(-abss.X, abss.Y)/2) -- bottom left
local c4 = absp + (Vector2.new(-abss.X, -abss.Y)/2) -- top left
return {c1,c2,c3,c4}
end
The function above will get each corners of the rectangle GuiObject.
And then, You can do something like :
-- code from before
local gui = x -- change "x" to whatever you want (GuiObject, ex. Frame, TextLabel, TextBox, etc)
local PlayerGui = game.Players.LocalPlayer:WaitForChild('PlayerGui')
local CurrentTouchingColors = {}
gui:GetPropertyChangedSignal('AbsolutePosition'):Connect(function()
local corners = getCorners(gui)
local pos1 = PlayerGui:GetGuiObjectsAtPosition(corners[1].X,corners[1].Y)
local pos2 = PlayerGui:GetGuiObjectsAtPosition(corners[2].X,corners[2].Y)
local pos3 = PlayerGui:GetGuiObjectsAtPosition(corners[3].X,corners[3].Y)
local pos4 = PlayerGui:GetGuiObjectsAtPosition(corners[4].X,corners[4].Y)
for i, v in pairs(pos1) do
if not table.find(CurrentTouchingColors, v.BackgroundColor3) then
table.insert(CurrentTouchingColors, v.BackgroundColor3)
end
end
for i, v in pairs(pos2) do
if not table.find(CurrentTouchingColors, v.BackgroundColor3) then
table.insert(CurrentTouchingColors, v.BackgroundColor3)
end
end
for i, v in pairs(pos3) do
if not table.find(CurrentTouchingColors, v.BackgroundColor3) then
table.insert(CurrentTouchingColors, v.BackgroundColor3)
end
end
for i, v in pairs(pos4) do
if not table.find(CurrentTouchingColors, v.BackgroundColor3) then
table.insert(CurrentTouchingColors, v.BackgroundColor3)
end
end
end)
This might look very confusing.
So What this script does do?
First, It gets the variables (gui, PlayerGui, CurrentTouchingColors)
As you can see, CurrentTouchingColors variable is table.
I setted it to table because to save the colors that gui is currently touching.
and after the line
gui:GetPropertyChangedSignal(‘AbsolutePosition’):Connect(function()
There are bunch of variables, and for i, v loops, right?
- Variables
There are total of 5 variables in the script, which are corners, pos1, pos2, pos3, pos4.
I will explain what they does.
-
corners - It gets the 4 corners of the rectangle GuiObject.
Example Picture
The red squares are the corners of the rectangle GuiObject at the middle. they are calculated by the function getCorners() at the top of this post. -
pos1, pos2, pos3, pos4 - These are the variables which store the GuiObjects at the position of all the corners Positions.
- 4 for i, v in pairs…
As you can see, there are four same things that starts with “for i, v in pairs(. . .) do”.
These are for loops and their work is to detect touching guis, and store each touching gui’s BackgroundColor3 to table CurrentTouchingColors, also it checks if the table has same color touching.
These were the explainations, I hope this reply helped you!
This won’t work on smaller objects
The script I’ve provided currently will not work on smaller objects that isnt touching the corner.
Example 1
Example 2
And The reason Example1 works and Example2 doesn’t work is because the script I’ve provided doesn’t calculate anything that isn’t touching the corner of the white UI, and in Example2, the blue frame is currently NOT touching the corners ( red squares ).
And To be honest, I couldn’t think of any other ways to make this (Example2) work.
anyways consider that If you are gonna use my script
For example 2, why not just calculate the distance between all the corners and use the results to find out if it touches between the 2 corners like raycasting?
To be honest, I can’t understand what are you saying.
Can you explain a bit deeper?
What I mean is that you calculate the distance between the 2 closest points of the Gui, draw an invisible line from the first corner to the second corner, and with this line you can tell whether the Gui touches the line or not.
Are you saying that
you get the two closest corners of the blue frame, then draw a line between two corners, and detect whether the blue frame touches the line or not?
Actually if we go like that, then this gets bit off-topic.
And why i am saying this is because, you are trying to get the guis that the main gui is Touching, then get the colors of the guis that main gui is touching. but this is getting a TouchStatus of 2 guis, then get the color of the gui that isn’t main.
anyways, it is possible to get the touch status of the part if you actually set the gui that you want to check if it is touching main gui.
getTouchStatus(maingui, gui) = true or false
and then
getColorOfGui(gui) if getTouchStatus(maingui, gui)
It will go something like that.
And, I am actually working on some works that is related to this, and I can tell how to get touch status correctly.
Yea… to get touch status between two guis, you can first get corners of main gui
local function getCorners(ui:GuiObject)
local absp = ui.AbsolutePosition
local abss = ui.AbsoluteSize
local c1 = (absp + Vector2.new(abss.X, abss.Y)/2) + abss/2 -- bottom right ++
local c2 = (absp + Vector2.new(-abss.X, abss.Y)/2) + abss/2 -- bottom left -+
local c3 = (absp + Vector2.new(-abss.X, -abss.Y)/2) + abss/2 -- top left --
local c4 = (absp + Vector2.new(abss.X, -abss.Y)/2) + abss/2 -- top right +-
return {c1,c2,c3,c4}
end
-- just a function from my reply before, also I changed c1~c4 for later.
local corners = getCorners(maingui)
and then you can use this equation :
if ((b_r.X >= pos.X) and (b_r.Y >= pos.Y)) and ((b_l.X <= pos.X) and (b_l.Y >= pos.Y)) and ((t_l.X <= pos.X) and (t_l.Y <= pos.Y)) and ((t_r.X >= pos.X) and (t_r.Y <= pos.Y)) then
-- do something
end
note : I will talk about “b_r” and “pos” later
And the equation above is from the module I am currently working on.
And full function of getting touch status is ( its from my module )
function GetTouchStatus(gui1:GuiObject, gui2:GuiObject)
local c1 = getCorners(gui1)
local c2 = getCorners(gui2)
local function check(t:{Vector2}, pos:Vector2)
local b_r = t[1]
local b_l = t[2]
local t_l = t[3]
local t_r = t[4]
local res = false
if ((b_r.X >= pos.X) and (b_r.Y >= pos.Y)) and ((b_l.X <= pos.X) and (b_l.Y >= pos.Y)) and ((t_l.X <= pos.X) and (t_l.Y <= pos.Y)) and ((t_r.X >= pos.X) and (t_r.Y <= pos.Y)) then
res = true
end
return res
end
local res = false
for i = 1, #c1 do
local ch = check(c2, c1[i])
if ch then res = true end
end
for i = 1, #c2 do
local ch = check(c1, c2[i])
if ch then res = true end
end
return res
end
the function getCorners(gui) returns table of corner positions.
and function check(t, pos) returns if a position is inside of 4 positions of table “t”. (table “t” is a result from function getCorners(maingui) )
I am currently tired to explain everything, so just ask things that you can’t understand in replies.
Can you show me the final script pls
what do you mean?
the entire module??
yes if you don’t mind ?
Ignore this
local module = {}
local function getCorners(gui:GuiObject, returnAsTable:boolean?) : Vector2 | {Vector2}
returnAsTable = returnAsTable or false
local absp = gui.AbsolutePosition
local abss = gui.AbsoluteSize
local c1 = (absp + Vector2.new(abss.X, abss.Y)/2) + abss/2 -- bottom right ++
local c2 = (absp + Vector2.new(-abss.X, abss.Y)/2) + abss/2 -- bottom left -+
local c3 = (absp + Vector2.new(-abss.X, -abss.Y)/2) + abss/2 -- top left --
local c4 = (absp + Vector2.new(abss.X, -abss.Y)/2) + abss/2 -- top right +-
if returnAsTable then
return {c1, c2, c3, c4}
else
return c1, c2, c3, c4
end
end
function module:GetTouchStatus(gui1:GuiObject, gui2:GuiObject)
local c1 = getCorners(gui1, true)
local c2 = getCorners(gui2, true)
local function check(t:{Vector2}, pos:Vector2)
local b_r = t[1]
local b_l = t[2]
local t_l = t[3]
local t_r = t[4]
local res = false
if ((b_r.X >= pos.X) and (b_r.Y >= pos.Y)) and ((b_l.X <= pos.X) and (b_l.Y >= pos.Y)) and ((t_l.X <= pos.X) and (t_l.Y <= pos.Y)) and ((t_r.X >= pos.X) and (t_r.Y <= pos.Y)) then
res = true
end
return res
end
local res = false
for i = 1, #c1 do
local ch = check(c2, c1[i])
if ch then res = true end
end
for i = 1, #c2 do
local ch = check(c1, c2[i])
if ch then res = true end
end
return res
end
return module
non-related functions, properties are deleted.
Thank you for your help
I needed this to do realistic physics with Gui.
Can I ask you how you did it with rotation??
For the rotation I had the idea of using the “Scratch” site to make the Gui because Scratch is in 2D so for me it’s Gui . I’m currently in the process of rotating it but it’s not easy to do.
I mean, you did get the “true” output when that image touches the slope.
And slope is rotated, how did you manage to get touch status correctly with a gui rotated?