Expanding/growing circle issue

We all know those expanding circles that are usually used when an impact happens; the player is supposed to just jump and done.

The problem I’m having is actually making them; using unions or hollow circle meshes shows an undesirable stretch upon reaching a certain distance that not only looks bad but, if collision damage is added, over time they become impossible to dodge.

My most successful attempt was to make a circle of parts; these will slowly increase their distance from the origin and their amount… which works!

image

BUT only in runmode, playtesting (prob ingame too) showcases flickering generation; sometimes completing the circle, sometimes not.

image

Temporal workaround was not destroying the parts until attack is done, which fortunaly works but causes lag too quickly due to the humongous amount of parts so I won't consider it a solution.

Here’s a roughly made function made out of my full code:

Code
local PartFolder = Instance.new("Folder")
local Origin: BasePart = script.Parent
PartFolder.Parent = workspace

function GrowingCircle()
	local fullCircle = 2 * math.pi
	local numberOfParts = 8                  -- Initial number
	local radius = 1.8                       -- Initial distance from origin
	local CircleMultiplier = 40              -- Maximum distance measurement

	local function getXAndZPositions(angle)
		local x = math.cos(angle) * radius
		local z = math.sin(angle) * radius
		return x, z
	end

	local function CreatePart()
		local part = Instance.new("Part")
		part.Size = Vector3.new(1.5, 0.5, 0.5)
		part.Anchored = true
		part.CanCollide = false
		part.Material = Enum.Material.Neon
		part.TopSurface = Enum.SurfaceType.Smooth
		part.Color = Color3.fromRGB(255, 88, 58)
		part.Parent = PartFolder

		part.Touched:Connect(function(hit)
			if hit.Parent:FindFirstChild("Humanoid") then
				hit.Parent.Humanoid:TakeDamage(15)
			end
		end)
		return part
	end

	for i = 1, CircleMultiplier do
		for _ = 1, numberOfParts do
			CreatePart()
		end

		for i, part in pairs(PartFolder:GetChildren()) do
			local angle = i * (fullCircle / #PartFolder:GetChildren())
			local x, z = getXAndZPositions(angle)

			local position = (Origin.CFrame * CFrame.new(x, 0, z)).Position
			local lookAt = Origin.Position

			part.CFrame = CFrame.new(position, lookAt)
		end
		task.wait(0.1)
		radius = radius + 1.5
		numberOfParts = numberOfParts + 7
		PartFolder:ClearAllChildren()
	end
	PartFolder:ClearAllChildren()
end
-- Effect may not be visible first time, run in a loop

Help will be much appreciated!!

2 Likes

Can’t you just use TweenService on a mesh?

That was the first thing I tried, but as mentioned on the post; when increasing the growing too much, they create a weird strech that is not what im looking for.

Could you send an image of that?

They only want the inner radius to increase, not the thickness of the mesh as well.

image
can be seen that the “collision” got bigger when distance is increased (using a dummy as test)

This doesn’t happen with my code. Both unions and meshes have the same issue

The problem here, is that you’re not scaling the lengths of the part as the radius increases, so gaps will appear

Now I get it, my best guess would also be just using parts and increasing the amount depending on what size the circle currently is at

While that would work I feel like adding new parts would be a better method because scaling them would make the circle look more low-poly the bigger it gets

If the circle initially has a high number of parts then it’s not really an issue.

I compensate this by increasing the amount of parts every loop which works on runmode
(also tried doing what ur saying but ends with a weird effect)

I dont care about the method, your idea could be the key but maybe idk how to execute it. If I get a working code that also works in playtesting (no matter the method) I’ll be happy

True, but I feel like cloning would also be easier to code, I can try to code it if this still is an issue by tomorrow (and if I don’t forget) but I don’t have time atm

I’m not sure why you’re deleting and regenerating parts every iteration, this will definitely cause lag.

Ironically, not doing so causes more lag.

If there are 5 parts around a circle and I want to add one more, doing so would be 10 times more difficult by having to modify the positions of every part for it to look good with the new part added.

Regenerating the thing again but this time with the extra part is way easier, also i dont think this will change anything.

You’re modifying the positions every iteration anyways though?

No, i mean modifying the positions of the already existing parts (if I dont delete them). Its easier to just generate it again

ok nvm I was wrong… That was exactly the answer, not generating but positioning all the parts again.

Despite me making the whole code, u got the idea so I’ll just say you solved it.
Heres the working code for anyone wondering:

local PartFolder = Instance.new("Folder")
local Origin: BasePart = script.Parent
PartFolder.Parent = workspace

function GrowingCircle()
	local fullCircle = 2 * math.pi
	local numberOfParts = 8                  -- Initial number
	local radius = 1.8                       -- Initial distance from origin
	local CircleMultiplier = 40              -- Maximum distance measurement

	local function getXAndZPositions(angle)
		local x = math.cos(angle) * radius
		local z = math.sin(angle) * radius
		return x, z
	end

	local function CreatePart()
		local part = Instance.new("Part")
		part.Size = Vector3.new(1.5, 0.5, 0.5)
		part.Anchored = true
		part.CanCollide = false
		part.Material = Enum.Material.Neon
		part.TopSurface = Enum.SurfaceType.Smooth
		part.Color = Color3.fromRGB(255, 88, 58)
		part.Parent = PartFolder

		part.Touched:Connect(function(hit)
			if hit.Parent:FindFirstChild("Humanoid") then
				hit.Parent.Humanoid:TakeDamage(15)
			end
		end)
		return part
	end
	
	local function DeclarePosition()
		for i, part in pairs(PartFolder:GetChildren()) do
			local angle = i * (fullCircle / #PartFolder:GetChildren())
			local x, z = getXAndZPositions(angle)
			
			local position = (Origin.CFrame * CFrame.new(x, 0, z)).Position
			local lookAt = Origin.Position
			
			part.CFrame = CFrame.new(position, lookAt)
		end
	end
	
	for i = 1, CircleMultiplier do
		for i = 1, 7, 1 do
			CreatePart()
		end
		
		DeclarePosition()
		task.wait(0.1)
		radius = radius + 1.5
	end
	PartFolder:ClearAllChildren()
end
1 Like

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