Particles in Viewports

Good Morning everyone. I am just testing/playing around with viewports and wondering is there a way to display particle effects in them?

Here you can see I have a couple swords:

In my script I call this module script which just gives the sword rotation within the viewport. I am wondering how I can display particles within this module:

local runService = game:GetService("RunService")

local ViewportUtil = {}

function ViewportUtil:SetupModelPreview(viewportFrame, model)
	local camera = Instance.new("Camera")
	camera.CFrame = CFrame.new(Vector3.new(0, 0, 3.3), Vector3.new(0, 0, 0))
	camera.Parent = viewportFrame
	viewportFrame.CurrentCamera = camera

	local modelClone = model:Clone()
	modelClone.Parent = viewportFrame

	-- Use per-sword orientation if available
	local orientationValue = model:FindFirstChild("PreviewOrientation")
	local orientationVector = orientationValue and orientationValue:IsA("Vector3Value") and orientationValue.Value or Vector3.new(-90, 0, 0)

	modelClone:SetPrimaryPartCFrame(CFrame.new(0, 0, 0) * CFrame.Angles(
		math.rad(orientationVector.X),
		math.rad(orientationVector.Y),
		math.rad(orientationVector.Z)
		))

	for _, part in pairs(modelClone:GetDescendants()) do
		if part:IsA("BasePart") then
			part.Anchored = true
		end
	end

	-- Random spin parameters for each sword
	local offset = math.random() * 360 -- Random starting angle in degrees
	local speedMultiplier = 0.5 + math.random() * 1.5
	local angle = offset

	local connection
	connection = runService.RenderStepped:Connect(function(deltaTime)
		if not modelClone or not modelClone.PrimaryPart or not viewportFrame:IsDescendantOf(game) then
			connection:Disconnect()
			return
		end

		angle = (angle + 60 * deltaTime * speedMultiplier) % 360 -- Random speed applied
		local rotation = CFrame.Angles(0, 0, math.rad(angle)) -- Z-axis rotation

		modelClone:SetPrimaryPartCFrame(
			CFrame.new(0, 0, 0) *
				CFrame.Angles(math.rad(orientationVector.X), math.rad(orientationVector.Y), math.rad(orientationVector.Z)) *
				rotation
		)
	end)
end

return ViewportUtil

Here is what it looks like in game:
image

I have tried a couple ways but all have failed. The swords all have the particle emitters under their handle.

Thanks for the help!

I would assume I add a for loop like this:

for _, desc in ipairs(modelClone:GetDescendants()) do
		if desc:IsA("ParticleEmitter") or desc:IsA("Trail") or desc:IsA("Beam") then
			if desc:IsA("ParticleEmitter") then
				desc.Enabled = true
			end
		end
	end

In my module but I dont see it being displayed in the view port

Viewports are insanely limited, one of their downsides is that they cant render particles, surface guis or anything similar.

Best thing you can do is to add some text that just mentions its a special item with specific particles, such as “Special: Fire Particles”

Ah man that sucks. Alright that would make more sense because I even went and tried making fake particles with billboardguis for tests or work-arounds :sob:.

Alright thanks a lot!

1 Like

I will add on, if you’re bothered (or can find an existing system), you could implement UI-Based particles that render behind the viewport frame. It won’t line up with the sword model, but it’ll get the point of particles across well enough.

1 Like

thats actually a good shout :thinking: The method im using is actually cloning a template Button for the swords so sure it wont directly be coming from the sword but in terms of lining up?? If I go down this path It should be good enough if I size it well.

Once again I appreciate it :saluting_face:

I also checked out your lighting Test place. It seems pretty clean man Nice job on it

1 Like