How would I make it so that if a Frame shows up and detects that there's a Frame already Visible in that position, and so how would I make the Frame move up other Frames that are touching it?
Gui Collision/Making Space for new Frame?
2 answers
I created a simple ScreenGui wrapper that implements collision detection.
Canvas = {
collision = false;
}
function Canvas.new(p)
local ob = setmetatable({}, {__index = Canvas})
p = p or false
if not p then
local r = Instance.new("ScreenGui")
ob._gui = r
else
ob._gui = p
end
return ob
end
function Canvas:getPoint(point)
for k, v in next, self._gui:getChildren() do
if v.AbsolutePosition.x + v.AbsoluteSize.x >= point.x and v.AbsolutePosition.y + v.AbsoluteSize.y >= point.y
and v.AbsolutePosition.x <= point.x and v.AbsolutePosition.y <= point.y then
return v
end
end
return false
end
function Canvas:setHandler(callback)
self['collision'] = callback
end
function Canvas:add(item)
item.Parent = self._gui
local c = self:getPoint(item.AbsolutePosition)
if c then
if self.collision then
self.collision(self, item, c)
end
end
return item
end
function Canvas:move(item, pos)
local _g = Instance.new('Frame')
_g.BackgroundTransparency = 1
_g.Position = pos
_g.Parent = self._gui
local ap = _g.AbsolutePosition
_g:Destroy()
local c = self:getPoint(ap)
item.Position = pos
if c then
if self.collision then
self.collision(self, item, c)
end
end
end
function Canvas:setParent(p)
self._gui.Parent = p
end
You create the wrapper with Canvas.new, which accepts an optional argument that's the ScreenGui object to wrap, if not provided it will create a new one. You will need to set its parent. That will return the object wrapper which have some handy methods:
Canvas:move(item, pos) Moves the GUI element item to UDim2 pos checking for collisions
Canvas:add(item) Adds GUI element item to the underlying ScreenGui checking for collision.
Canvas:setHandler(func) Sets function func as the collision handler
Canvas:setParent(p) Sets the parent of the underlying ScreenGui to p
Example:
cv = Canvas.new() --Create the wrapper
cv:setParent(game.Players.LocalPlayer.PlayerGui) --Set the parent to be PlayerGui
cv:setHandler(
function(self, a, b)
self:move(a, UDim2.new(0, a.AbsolutePosition.x, 0, b.AbsolutePosition.Y-a.AbsoluteSize.Y))
end
) --Set the collision handler. The handler is called with 3 arguments, a reference to the wrapper object, and the GUIs that collided. We move the first GUI to be on top of the second
template = Instance.new("Frame") --Just a frame template that we will clone to populate the wrapper
template.Size = UDim2.new(0,50,0,50)
template.BackgroundColor3 = BrickColor.Random().Color
for i = 1, 4 do
local c = cv:add(template:Clone())--Add the element to the wrapper
cv:move(c, UDim2.new(0, 50,0, 500))--Move the element
end
If you run that example, you will see that every element is stacked.
Feel free to modify the code and expand its functionality, also PM me any questions.
you should give an example of a script you made ior borrowed in the future, but i dont think you can do that but you could do the position away from that particular gui like i dont know if this is a script:
move.frame.vector3.position(the position here) --- the position of ur frame
but i am not the expert that does the script perfect but you can only make the frame appear somewhere other than where the diffrent frames are.
1 comment
I dont think move is something :/
This discussion is preserved as it was. New answers, comments, and votes are closed.

2 comments
http://wiki.roblox.com/index.php?title=Collision_detection_for_GUI%27s
lol so complicating :/ I wouldn't be able to edit it to my needs :( :'(