Trying to recreate the Forza Horizons 5 trail, however its laggy... how can I fix/recreate?


The video does most of the talking, however, this is a local script in starterplayerscripts and it stores the parts in starterpack when they are invisible so they don’t reappear when the player has passed them. I know this is not the most efficient way of doing this but I did this entirely on my little knowledge a few months ago and I’m wondering how to fix it now. I am willing to recreate the concept as well, but any advice for a less laggy/more efficient way to do this is helpful. Also, if possible I want to be able to manipulate it around a trail that I am going to make later. Thanks.
Script attached below as well:

local player = game.Players.LocalPlayer
local MinDistance = 0 
local MaxDistance = 20
local block = game.Workspace:WaitForChild("block")

game:GetService("RunService").Heartbeat:Connect(function()
local character = player.Character or player.CharacterAdded:Wait()
local humanoidP = character.PrimaryPart
	for _, part : MeshPart in game.Workspace.trail:GetChildren() do
		local distance = (humanoidP.Position - part.Position).Magnitude
		part.Transparency = 1 - (math.clamp(distance, MinDistance, MaxDistance) / MaxDistance)
		part.Touched:Connect(function()
			part.Parent = game.StarterPack.ArrowStore
		end)
	end
end)


block.Touched:Connect(function()
	for _, part:MeshPart in game.StarterPack.ArrowStore:GetChildren() do
		part.Parent = game.Workspace.trail
	end
end)

there are quite a few issues with your code.

Like this. You never want to have something that yields inside a loop that runs every frame.
if the character doesn’t exist it will wait for it which is useless because the frame next to it will do it again.

game:GetService("RunService").Heartbeat:Connect(function()
local character = player.Character or player.CharacterAdded:Wait()

Your second issue is that you are connecting a new Touched event for every part every frame. This builds up really fast and once you touch 1 part all those events connected to it will fire and because there are so many it causes a lag spike. Instead you should connect 1 event for each part once.

To fix the character issue you should parent your script to StarterCharacterScripts.
Something like this

-- LocalScript in StarterCharacterScripts
local RunService = game:GetService("RunService")

local character = script.Parent
local humanoidRootPart = character.HumanoidRootPart

local MinDistance = 0
local MaxDistance = 20
local block = game.Workspace:WaitForChild("block")

local trailParts = game.Workspace.trail:GetChildren()

--> listen for when each part is touched, once!
for i, trailPart in trailParts do
	trailPart.Touched:Connect(function()
		trailPart.Parent = game.StarterPack.ArrowStore
	end)
end

RunService.Heartbeat:Connect(function()
	for _, trailPart in trailParts do
		local distance = (humanoidRootPart.Position - trailPart.Position).Magnitude
		trailPart.Transparency = 1 - (math.clamp(distance, MinDistance, MaxDistance) / MaxDistance)
	end
end)

block.Touched:Connect(function()
	for _, trailPart in game.StarterPack.ArrowStore:GetChildren() do
		trailPart.Parent = game.Workspace.trail
	end
end)
1 Like

This works without lag! Had to change a few minor things ofc but thank you. I might end up doing a beam so it can be manipulated since the trails I plan on using this on will be more complex but I could also end up using this so thank you.

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