How can I make a ring that can be rendered real time?

  1. What do you want to achieve?
    I want to make a ring that can be change real time such as size and thickness:

  2. What is the issue?
    If I use a union or a mesh, the middle hole size gets scaled as well which I don’t want
    image

  3. What solutions have you tried so far?
    I tried using a 0.99 transparency glass material part in the middle but it made it shiny which I want to avoid

Its a bit hard to understand what you mean by ‘ring’
Do you mean with parts? Such as unions? Where one smaller cylinder is removed from the center of a larger cylinder?

I noticed you said Unions, but couldn’t you just create a new union and destroy the old one, but the new one have a larger or smaller inner cylinder?

Maybe this would help, sorry I don’t quite understand.

https://create.roblox.com/docs/reference/engine/classes/BasePart#SubtractAsync

Yes, that is exactly what I mean, a smaller cylinder be removed from the center.

And wouldn’t making a new union real time be costly with performance?

Honestly I am not familiar enough with making unions to know, I would think it a pretty cheap process if you are just hollowing a cylinder, but, idk.

What is your use case? What are you doing with the ring, and how often do you need to resize (scale) it?

I want to make a ring for a tower defense game for stuff such as range (the hollowed out is for showing how close you can place towers together or for towers that move in a circle around the placement position to show their travel path) and I would need to update it pretty much almost every frame as I want my ring to scale when once you click on a tower to visualize it’s range

Forgive me, if I am just totally not getting it, but wouldn’t you only need to update the scale of the ring, each time you clicked a tower? That would be once per click.

Also, if each tower has a set range (such as Tower Type A, has rage 4, and Tower Type B has range 2) couldn’t you just at server startup or even client login, generate 1 ring per tower type, and store in replicated storage, to be cloned and displayed when the corresponding tower is selected?

Or even if the tower’s values can change, such as upgrades, you could still generate one ring per tower, and keep it in replicated, and only modify it when the tower is upgraded.

While yes, I could do that, but I want the ring to have an animation where it scales up in a short period of time

depending on the use case, you could probably just use two cylinders
just make a thinner one, and then a slightly thicker one
the thinner one will be bigger and control the overall size
and the thicker one will be smaller and control the hole size and width

but if that doesnt match with what you’re going for you could use some trig lol

The problem with that is that the color would still be different and make it a have a tint of the bigger one and the range visualizers are slightly transparent

Well, my final suggestion is, maybe just try the union bit, and see how expensive it is.
Other than that, maybe its ok to have 2 colors of cylinders, instead of the inner one being clear (hollow) maybe have it a different color to represent the inner area.

Ok, try this… it uses beams.

VariableRings.rbxl (37.5 KB)


function CreateRing(numParts)
	local model = Instance.new("Model")
	
	local part = Instance.new("Part")
	part.CanCollide = false
	part.CanQuery = false
	part.CanTouch = false
	part.Anchored = true
	part.Size = Vector3.new(1,1,1)
	part.Transparency = 1
	
	local att = Instance.new("Attachment")
	att.Parent = part
	att.CFrame = CFrame.new()*CFrame.Angles(0,0,math.rad(90))
	att.Name = "Attachment"	
	
	local beam = Instance.new("Beam")
	beam.Segments = 1
	beam.Width0 = 1
	beam.Width1 = 1
	beam.Attachment0 = att
	beam.Parent = part
	
	local deg = 360/numParts
	for n = 1,numParts do
		local p = part:Clone()
		p.Name = "Part"..n
		p.CFrame = CFrame.new()*CFrame.Angles(0,math.rad((n-1)*deg),0)
		p.Attachment.CFrame = p.Attachment.CFrame + Vector3.new(5,0,0)
		p.Parent = model
	end
	for n = 1,numParts do
		local p = model:FindFirstChild("Part"..n)
		if n < numParts then
			p.Beam.Attachment1 = model:WaitForChild("Part"..(n+1)).Attachment
		else
			p.Beam.Attachment1 = model:WaitForChild("Part1").Attachment
		end
	end
	return model
end

function ResizeRing(ring,innerRadius,outterRadius)
	if innerRadius>= outterRadius then 
		return
	end
	local width = outterRadius - innerRadius
	local pos = innerRadius+(width/2)
	for n = 1,#ring:GetChildren() do
		local part = ring:FindFirstChild("Part"..n)
		part.Attachment.Position = Vector3.new(pos,0,0)
		part.Beam.Width0 = width
		part.Beam.Width1 = width
	end
end

function ColorRing(ring,colorSequence,transparencySequence)
	for n = 1,#ring:GetChildren() do
		local part = ring:FindFirstChild("Part"..n)
		part.Beam.Color = colorSequence
		part.Beam.Transparency = transparencySequence
	end
end

------ Implementation

local myRing = CreateRing(24)
myRing.Parent = workspace
myRing:PivotTo(CFrame.new(0,1,0))
ResizeRing(myRing,5,20)
ColorRing(myRing,ColorSequence.new(Color3.new(0, 0, 1)),NumberSequence.new(0))




1 Like

Guy, this’s one is very easy. Use cylinder handle adornment, and change InnerRadius for hole. Don’t forgot to set adornee. ALso, If you need it uniteractable, make it into workspace.
image

2 Likes

This is exactly what I want, thank you!