hey guys, I made a ring creator similar to TSB’s one, here’s the result ![]()
and here’s the code for it:
big block of code
local rings = {}
rings.__index = rings --MUST HAVE!!
--// SERVICES AND MISC
local tweenService = game:GetService("TweenService")
local ringFolder = workspace:WaitForChild("Rings")
local count = 0
local cleanup = true
--// TWEENINFO
local default = TweenInfo.new(5, Enum.EasingStyle.Linear, Enum.EasingDirection.Out, 0, false, 0)
local default2 = TweenInfo.new(5.5, Enum.EasingStyle.Linear, Enum.EasingDirection.In, 0, false, 0)
--// FUNCTIONS
function setParent(parent, ...)
local children = {...}
for i, v in children do
v.Parent = parent
end
end
function newBeam()
--To set: att0, att1, color and parent
local beam = script.Beam:Clone() --Beam to use
return beam
end
function cleanup(garbage)
if not cleanup then return end
print("Cleaned up ".. garbage.Parent.Name)
for i, v in garbage do
v:Destroy()
end
end
function createRing()
--// CREATING NEW RING FOLDER
local mainFolder = workspace:FindFirstChildOfClass("Folder") --> nil, diff folder
local parentFolder = Instance.new("Folder")
--If not found in workspace
if not (mainFolder and mainFolder.Name == "Rings") then
mainFolder = Instance.new("Folder")
mainFolder.Parent = workspace
end
parentFolder.Parent = mainFolder
parentFolder.Name = "Ring".. count
--// BEAMS
local b0 = newBeam()
local b1 = newBeam()
b0.Name = "Beam0"
b1.Name = "Beam1"
--// ATTACHMENTS
local a0 = Instance.new("Attachment")
local a1 = Instance.new("Attachment")
a0.Name = "Attachment0"
a1.Name = "Attachment1"
--// NUMVALUE (FOR TRANSPARENCY)
local nv = Instance.new("NumberValue")
return {
["Parent"] = parentFolder,
["Beam0"] = b0,
["Beam1"] = b1,
["Att0"] = a0,
["Att1"] = a1,
["NumberValue"] = nv,
}
end
--// MODULE FUNCTIONS
rings.Create = function(
cf: CFrame,
radius: number,
speed: number,
color: Color3?,
startWidth: number?,
endWidth: number?
)
--Default values
color = color or Color3.new(1, 1, 1)
startWidth = startWidth or 1
endWidth = endWidth or 0.18
local properties = {
["Attachment0"] = {
["CFrame"] = cf + (cf.LookVector * Vector3.new(0, 0, radius))
},
["Attachment1"] = {
["CFrame"] = cf + (cf.LookVector * Vector3.new(0, 0, -radius))
},
["Beam0"] = {
["CurveSize0"] = (radius * (4/3)),
["CurveSize1"] = -(radius * (4/3)),
["Width0"] = endWidth,
["Width1"] = endWidth
},
["Beam1"] = {
["CurveSize0"] = -(radius * (4/3)),
["CurveSize1"] = (radius * (4/3)),
["Width0"] = endWidth,
["Width1"] = endWidth
},
["NumberValue"] = {
["Value"] = 1
},
["Settings"] = {
["Origin"] = cf,
["Speed"] = speed,
["Color"] = color,
["StartWidth"] = startWidth
}
}
--local tbl = {properties, speed, color, startWidth}
return setmetatable(properties, rings)
end
function rings:Spawn()
--// INITIATING
local ring = createRing()
local parent = ring.Parent
local beam0 = ring.Beam0
local beam1 = ring.Beam1
local att0 = ring.Att0
local att1 = ring.Att1
local numberValue = ring.NumberValue --For beam transparency
--Preset values
--"self" is the ring we just created and passed thru
local color = ColorSequence.new(self.Settings.Color)
local transparencyTween = tweenService:Create(numberValue, default2, self["NumberValue"])
beam0.Width0 = self.Settings.StartWidth
beam0.Width1 = self.Settings.StartWidth
beam1.Width0 = self.Settings.StartWidth
beam1.Width1 = self.Settings.StartWidth
print("started!")
att0.CFrame = self.Settings.Origin
att1.CFrame = self.Settings.Origin
beam0.Attachment0 = att0
beam0.Attachment1 = att1
beam0.Color = color
beam1.Attachment0 = att0
beam1.Attachment1 = att1
beam1.Color = color
--Finally set the parent for each object
setParent(parent, beam0, beam1, att0, att1, numberValue)
task.spawn(function()
for i, v in parent:GetChildren() do
if self[v.Name] then
print("created tween for ", v.Name)
local tween = tweenService:Create(v, default, self[v.Name])
tween:Play()
end
end
numberValue:GetPropertyChangedSignal("Value"):Connect(function()
beam0.Transparency = NumberSequence.new(numberValue.Value)
beam1.Transparency = NumberSequence.new(numberValue.Value)
end)
transparencyTween:Play()
transparencyTween.Completed:Wait()
numberValue:Destroy()
cleanup(ring)
end)
count += 1
print("ended!")
end
return rings
I rewrote the code so it uses helper functions and allows cleanup! (by the way, the video shows multiple rings, the module won’t be used like this in the real game)
if there is any suggestions about optimizations or rewrites, please let me know! thank you ![]()
