I have a plugin, GUI Studio, and I want to add support for rotated GUIs. Right now, I'm trying to position pseudo-resize handles (just other GUIs) on the left/top/bottom/right sides of the GUI no matter it's rotation.
I will present the Left handle code. The issue I am having is that it is slightly below the center of the left side (imagine the left side of a GUI and it rotated and now imagine where you could see a resize-handle at the center of that side). It's not there, and always ends up slightly below the correct point.
Here is how I find the direction from the rotation
function GetGuiDirection(x, gui) local rotation; if x == "Left" then rotation = math.rad(gui.Rotation+270) elseif x == "Top" then rotation = math.rad(gui.Rotation) elseif x == "Right" then rotation = math.rad(gui.Rotation+90) elseif x == "Bottom" then rotation = math.rad(180+gui.Rotation) end return Vector2.new((math.sin(rotation)), (math.cos(rotation))) end
And here is how I am positioning the LEFT resize handle:
local left_direction = GetGuiDirection("Left", gui_x) local solvedx = ((posx+sizex/2)-rhandle.AbsoluteSize.X) + ((sizex/2) * left_direction.x) local solvedy = ((posy+sizey/2)-rhandle.AbsoluteSize.Y/2) - ((sizex/2) * left_direction.y) print(((posy+sizey/2)-rhandle.AbsoluteSize.Y/2), " - ", ((sizex/2) * left_direction.y)) left.Position = UDim2.new(0,solvedx,0,solvedy);
Just notice that the math in the first set of parenthesis on the solve_ variables is just to get the center of whatever GUI is currently selected. In general, everything is correct and it gets positioned in the same relative-coordinates no matter the rotation/size. It's just that it is slightly below (on the Y axis) where it should be.
Does anyone have any experience with this sort of math and can explain a solution - or the problem?
GUI objects in ROBLOX are positioned based on their top-left coordinates when they're not rotated, and they're rotated based on their center coordinates. This can cause some problems when figuring out where things are rendered.
Since GUI objects are rotated around their center coordinates, I decided to make a function that told me where the center coordinates are:
local function GetCenterOfGuiObject(guiObject) return Vector2.new( guiObject.AbsolutePosition.x + guiObject.AbsoluteSize.x/2, guiObject.AbsolutePosition.y + guiObject.AbsoluteSize.y/2 ) end
Having this function, we can now focus on finding the centers of the edges, which we can then use to determine the placements of the handles. Things to note:
Keeping these things in mind, I wrote a simple function to help me determine where the edges of any GUI object would be:
local function GetCenterOfEdge(guiObject, edge) local center = GetCenterOfGuiObject(guiObject); local size = guiObject.AbsoluteSize; local rotation = math.rad(guiObject.Rotation); if edge == "Left" then size = Vector2.new(size.x, size.x) -- moves like a circle rotation = rotation - math.pi; elseif edge == "Top" then size = Vector2.new(size.y, size.y) rotation = rotation - math.pi/2; elseif edge == "Right" then size = Vector2.new(size.x, size.x) rotation = rotation; elseif edge == "Bottom" then size = Vector2.new(size.y, size.y) rotation = rotation + math.pi/2; end rotation = -rotation; -- clockwise return center + (size/2) * Vector2.new( math.cos(rotation), -math.sin(rotation) -- to fix flipped y-axis ) end
Now that we know the centers of any edge, we can easily position the top-left of our handles relative to that. I'm sure you can figure out how to do that, however. :P