Last active
February 15, 2022 13:11
-
-
Save RealEthanPlayzDev/c4e87c5fe87297299d3a7782fccfe391 to your computer and use it in GitHub Desktop.
Geometry Lines Background Rendering
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--[[ | |
File name: GeometryLinesBackground.luau | |
Author: RadiatedExodus (ItzEthanPlayz_YT/RealEthanPlayzDev) | |
Created at: February 11, 2022 | |
--]] | |
local serv = { | |
RunService = game:GetService("RunService"); | |
Debris = game:GetService("Debris"); | |
TweenService = game:GetService("TweenService"); | |
} | |
--// This can be technically static, having one GetPropertyChangedSignal for every new object would not work well with the memory anyways | |
local RbxWindowSize = workspace.CurrentCamera.ViewportSize | |
workspace.CurrentCamera:GetPropertyChangedSignal("ViewportSize"):Connect(function() | |
RbxWindowSize = workspace.CurrentCamera.ViewportSize | |
return | |
end) | |
--// Utility | |
local function InstanceTypeof(i: any) return if typeof(i) == "Instance" then i.ClassName else typeof(i) end | |
local function InvalidArgumentType(argnumber: number, funcname: string, expected: string, got: string) | |
return string.format("invalid argument #%d to '%s' (%s expected, got %s)", argnumber, funcname, expected, got) | |
end | |
local function GetRandomUDim2OffsetBasedOnRbxWindowSize(Rand: Random) | |
return UDim2.new(0, Rand:NextInteger(0, RbxWindowSize.X), 0, Rand:NextInteger(0, RbxWindowSize.Y)) | |
end | |
local function CreateDot() | |
local dot = Instance.new("Frame") | |
dot.Name = "Dot" | |
dot.Size = UDim2.new(0, 10, 0, 10) | |
dot.AnchorPoint = Vector2.new(0.5, 0.5) | |
dot.BorderSizePixel = 0 | |
dot.BackgroundColor3 = Color3.fromRGB(255, 255, 255) | |
return dot | |
end | |
--// https://devforum.roblox.com/t/drawing-a-path-with-uis/252604/2 | |
function drawPath(clineframe, startBtn, endBtn) | |
local startX, startY = startBtn.Position.X.Offset, startBtn.Position.Y.Offset | |
local endX, endY = endBtn.Position.X.Offset, endBtn.Position.Y.Offset | |
local Line = if not clineframe then Instance.new("Frame") else clineframe | |
Line.AnchorPoint = Vector2.new(0.5, 0.5) | |
Line.Size = UDim2.new(0, ((endX - startX) ^ 2 + (endY - startY) ^ 2) ^ 0.5, 0, 5) -- Get the size using the distance formula | |
Line.Position = UDim2.new(0, (startX + endX) / 2, 0, (startY + endY) / 2) -- Get the position using the midpoint formula | |
Line.Rotation = math.atan2(endY - startY, endX - startX) * (180 / math.pi) -- Get the rotation using atan2, convert radians to degrees | |
return Line | |
end | |
--\\ | |
--// CLASS GeometryLinesBackground | |
local GeometryLinesBackground = {} | |
GeometryLinesBackground.__index = GeometryLinesBackground | |
GeometryLinesBackground.__tostring = function() return "GeometryLinesBackground" end | |
function GeometryLinesBackground:_GetLineFromTwoDot(fd: Frame, sd: Frame) | |
for index, line in ipairs(self.__lines) do | |
if line.FirstDot == fd and line.SecondDot == sd then | |
return line, index | |
end | |
end | |
return | |
end | |
function GeometryLinesBackground:_RandomlyTweenDotInCameraSpace(dot) | |
local tw = serv.TweenService:Create(dot, TweenInfo.new(6, Enum.EasingStyle.Linear), {Position = GetRandomUDim2OffsetBasedOnRbxWindowSize(self.__rand)}) | |
tw.Completed:Connect(function() | |
if not self.__rendering then return end | |
self:_RandomlyTweenDotInCameraSpace(dot) | |
--// print("tweening") | |
end) | |
tw:Play() | |
return | |
end | |
function GeometryLinesBackground:StartRender(overridecurrentrendering: boolean?) | |
if not typeof(self.__rootframe) == "Instance" then return error("root frame not set", 2) end | |
if self.__rendering then | |
if overridecurrentrendering then | |
self:StopRender() | |
else | |
return error("already rendering, pass true to override", 2) | |
end | |
end | |
for i = 1, self.__amountofdots do | |
local dot = CreateDot() | |
dot.BackgroundColor3 = self.__dotbackgroundcolor3 | |
dot.Position = GetRandomUDim2OffsetBasedOnRbxWindowSize(self.__rand) | |
self:_RandomlyTweenDotInCameraSpace(dot) | |
dot.Parent = self.__rootframe | |
table.insert(self.__dots, dot) | |
end | |
self.__renderevent = serv.RunService.Heartbeat:Connect(function() | |
for _, dot: Frame in next, self.__dots do | |
for _, seconddot: Frame in next, self.__dots do | |
if seconddot ~= dot and (dot.AbsolutePosition - seconddot.AbsolutePosition).Magnitude <= 150 then | |
local linedata = self:_GetLineFromTwoDot(dot, seconddot) | |
if not linedata then | |
local line = Instance.new("Frame") | |
line.Name = "Line" | |
line.BorderSizePixel = 0 | |
line.BackgroundColor3 = self.__linebackgroundcolor3 | |
line.Size = UDim2.new(0, 0, 0, 0) | |
line.Parent = self.__rootframe | |
linedata = {FirstDot = dot, SecondDot = seconddot, Line = line} | |
table.insert(self.__lines, linedata) | |
end | |
linedata.Line.BackgroundTransparency = if self.__transparencyenabled then math.clamp((dot.AbsolutePosition - seconddot.AbsolutePosition).Magnitude, 1, 150) / 150 else 0 | |
drawPath(linedata.Line, dot, seconddot) | |
else | |
local line, index = self:_GetLineFromTwoDot(dot, seconddot) | |
if line then | |
table.remove(self.__lines, index) | |
serv.Debris:AddItem(line.Line, 0) | |
end | |
end | |
end | |
end | |
end) | |
self.__rendering = true | |
self.Rendering = true | |
return true | |
end | |
function GeometryLinesBackground:StopRender() | |
if self.__renderevent then self.__renderevent:Disconnect() end | |
self.__renderevent = nil | |
for _, line in next, self.__lines do | |
serv.Debris:AddItem(line.Line, 0) | |
end | |
table.clear(self.__lines) | |
for _, dot in next, self.__dots do | |
serv.Debris:AddItem(dot, 0) | |
end | |
table.clear(self.__dots) | |
self.__rendering = false | |
self.Rendering = false | |
return true | |
end | |
function GeometryLinesBackground:IsRendering() | |
return self.__rendering | |
end | |
function GeometryLinesBackground:SetAmountOfDots(newamount: number) | |
assert(InstanceTypeof(newamount) == "number", InvalidArgumentType(1, "SetAmountOfDots", "number", InstanceTypeof(newamount))) | |
assert(not self.__rendering, "attempt to set amount of dots while still rendering") | |
self.__amountofdots = newamount | |
self.AmountOfDots = newamount | |
return | |
end | |
function GeometryLinesBackground:SetRootFrame(newrootframe: GuiObject) | |
assert(InstanceTypeof(newrootframe) == "Instance", InvalidArgumentType(1, "SetRootFrame", "Instance", InstanceTypeof(newrootframe))) | |
assert(not self.__rendering, "attempt to set root frame while still rendering") | |
self.__rootframe = newrootframe | |
self.RootFrame = newrootframe | |
return | |
end | |
function GeometryLinesBackground:SetDotBackgroundColor3(newc3: Color3) | |
assert(InstanceTypeof(newc3) == "Color3", InvalidArgumentType(1, "SetDotBackgroundColor3", "Color3", InstanceTypeof(newc3))) | |
assert(not self.__rendering, "attempt to set dot color3 while still rendering") | |
self.__dotbackgroundcolor3 = newc3 | |
self.DotBackgroundColor3 = newc3 | |
return | |
end | |
function GeometryLinesBackground:SetLineBackgroundColor3(newc3: Color3) | |
assert(InstanceTypeof(newc3) == "Color3", InvalidArgumentType(1, "SetLineBackgroundColor3", "Color3", InstanceTypeof(newc3))) | |
assert(not self.__rendering, "attempt to set line color3 while still rendering") | |
self.__linebackgroundcolor3 = newc3 | |
self.LineBackgroundColor3 = newc3 | |
return | |
end | |
function GeometryLinesBackground:SetTransparencyEnabled(newtoggle: boolean) | |
assert(InstanceTypeof(newtoggle) == "boolean", InvalidArgumentType(1, "SetFarTransparencyEffect", "boolean", InstanceTypeof(newtoggle))) | |
assert(not self.__rendering, "attempt to set far transparency effect while still rendering") | |
self.__transparencyenabled = newtoggle | |
self.TransparencyEnabled = newtoggle | |
return | |
end | |
local function new(amountofdots: number?, rootframe: GuiObject?, randomseed: number?) | |
return setmetatable({ | |
__rootframe = rootframe; | |
__renderevent = nil; | |
__rand = if randomseed then Random.new(randomseed) else Random.new(); | |
__lines = {}; | |
__dots = {}; | |
__rendering = false; | |
__amountofdots = if typeof(amountofdots) == "number" then amountofdots else 35; | |
__dotbackgroundcolor3 = Color3.fromRGB(255, 255, 255); | |
__linebackgroundcolor3 = Color3.fromRGB(255, 255, 255); | |
__transparencyenabled = true; | |
--// Public variables | |
RootFrame = rootframe; | |
AmountOfDots = if typeof(amountofdots) == "number" then amountofdots else 35; | |
DotBackgroundColor3 = Color3.fromRGB(255, 255, 255); | |
LineBackgroundColor3 = Color3.fromRGB(255, 255, 255); | |
TransparencyEnabled = true; | |
Rendering = false; | |
}, GeometryLinesBackground) | |
end | |
return setmetatable({new = new}, {__call = new}) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment