Modulescript for rings needs reviewing!

hey guys, I made a ring creator similar to TSB’s one, here’s the result :sparkles:

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 :derp:

2 Likes

The code looks complicated in my opinion. If this is purely for creating a ring effect, then you can achieve the same effect by using a mesh and tweening its size and transparency.

local function createMesh(origin, speed, color, startSize)
	local mesh = script.MeshPart:Clone()
	mesh.CFrame = origin
	mesh.Color = color
	mesh.Size = startSize
	mesh.Parent = workspace
	game.TweenService:Create(mesh, TweenInfo.new(speed, Enum.EasingStyle.Linear), {
		Size = Vector3.new(20, 0, 20),
		Transparency = 1
	}):Play()
end

while true do
	createMesh(...)
	task.wait(1)
end

…Unless I’m missing something but yeah

5 Likes

there’s more customizability like brightness, textures, lightemission and all that
(I’m also just a bit salty if I wrote all this code just for it to be replaced with meshparts)

3 Likes

OOP is just so forced here :v::broken_heart:

Why do you need to clarify that it is a module script anyway?
As if is gonna change context :wilted_flower:


What the crime against humanity is that by the way?

2 Likes

I heard about OOP and wanted to try it HAHA

also that’s why I put this post in code review… so people yk, review my code?

2 Likes

could u give me the mesh for that?

1 Like

Sure this is the id: rbxassetid://6688106498

1 Like

alright, thanks so much!! :happy1:
(wrote so much code just for it to be discarded HAHA)

4 Likes

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.