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)
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)
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.