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?
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.