Audio script causing lag with a lot of parts

I am trying to make a Dynamic Audio script (dampens audio based on how far the sound travels through objects) however it is causing a whole lot of lag. I have a folder, "IgnoreFolder" that contains all the parts I want the audio dampening to ignore (basically so it doesn’t dampen small details in my game and make it sound weird). The script works by shooting a raycast from the sound to the camera and from the camera to the sound to get the positions the ray hits each parts and can use that to find distance through objects. I do this in a function called "calculateTotalDistance" where it runs in a loop over and over for every sound (the processing is done over a span of 0.5 seconds to reduce random lag spikes). When the script is ran with a ton of parts in the "IgnoreFolder", and the raycasts are sent out, there is extreme lag. This is because whenever it hits any part, it compares it with every single part in the "IgnoreFolder" until it finds out if or if it does not match any and does the same for every part the racast hits and every sound in the entire game. I tried using CollectionService however either I used it wrong or it doesnt work. With 6146 ignored parts and 513 sounds, i am getting about 10 fps

local Workspace = game:GetService("Workspace")
local Players = game:GetService("Players")
local TweenService = game:GetService("TweenService")
local RunService = game:GetService("RunService")
local CollectionService = game:GetService("CollectionService")

local partsFolder = Workspace:FindFirstChild("PartsFolder") -- sounds folder
local ignoreFolder = Workspace:FindFirstChild("IgnoreFolder") -- place parts to ignore in here

local player = Players.LocalPlayer
local camera = Workspace.CurrentCamera

local ignoreList = {}  --ignore list

local function updateIgnoreList()
	ignoreList = {}  -- reset ignore list
	for _, item in pairs(CollectionService:GetTagged("IgnoreTag")) do
		table.insert(ignoreList, item)
	end
end

for _, child in pairs(ignoreFolder:GetChildren()) do --tag all the parts in the ignore list
	if child:IsA("BasePart") or child:IsA("Model") then
		CollectionService:AddTag(child, "IgnoreTag")
	end
end

updateIgnoreList()

ignoreFolder.ChildAdded:Connect(function(child) --update ignore list if anything new is added
	if child:IsA("BasePart") or child:IsA("Model") then
		CollectionService:AddTag(child, "IgnoreTag")
		updateIgnoreList()
	end
end)

ignoreFolder.ChildRemoved:Connect(function(child)--update ignore list if anything new is removed
	if child:IsA("BasePart") or child:IsA("Model") then
		CollectionService:RemoveTag(child, "IgnoreTag")
		updateIgnoreList()
	end
end)
-- unrelated code after this until calculatetotaldistance
local function calculateTotalDistance(part)
	local hitsToCamera = {}
	local hitsFromCamera = {}

	local currentIgnoreList = {part} --temp ignore list to ignore current sound part
	for _, item in pairs(ignoreList) do
		table.insert(currentIgnoreList, item)
	end

	local character = player.Character
	if character then --ignore player to reduce mess up in math
		for _, child in pairs(character:GetDescendants()) do
			if child:IsA("BasePart") then
				table.insert(currentIgnoreList, child)
			end
		end
	end

	performRaycast(part.Position, camera.CFrame.Position, hitsToCamera, currentIgnoreList)
	performRaycast(camera.CFrame.Position, part.Position, hitsFromCamera, currentIgnoreList)
--more unrelated code after this

This issue is unrelated to the raycasts causing lag since without the ignorelist, I get a perfect 60fps.
Thank you for your help in advance

1 Like

I don’t know if this will help but this should improve performance by a tad

local Players = game:GetService("Players")
local TweenService = game:GetService("TweenService")
local RunService = game:GetService("RunService")
local CollectionService = game:GetService("CollectionService")

local partsFolder = workspace:FindFirstChild("PartsFolder") -- sounds folder
local ignoreFolder = workspace:FindFirstChild("IgnoreFolder") -- place parts to ignore in here

local player = Players.LocalPlayer
local camera = workspace.CurrentCamera

local ignoreList = {}  --ignore list

local function findobjinignore(obj : BasePart | Model) : number
    return table.find(ignoreList, obj)
end

local function IsValid(obj : BasePart | Model)
    return obj:IsA("BasePart") or obj:IsA("Model")
end

local function initPart(obj : BasePart | Model)
    if IsValid(obj) then
        CollectionService:AddTag(obj, "IgnoreTag")
        if not findobjinignore(obj) then
            table.insert(ignoreList, obj)
        end
    end
end

ignoreFolder.ChildAdded:Connect(initPart)
ignoreFolder.ChildRemoved:Connect(function(child)--update ignore list if anything new is removed
	if IsValid(child) then
		CollectionService:RemoveTag(child, "IgnoreTag")
        
        local found = findobjinignore(child)
        if found then -- just incase
		    table.remove(ignoreList, found)
        end
	end
end)


for _, child in ignoreFolder:GetChildren() do --tag all the parts in the ignore list
	initPart(child)
end
local function calculateTotalDistance(part)
	local hitsToCamera = {}
	local hitsFromCamera = {}

	local currentIgnoreList = table.clone(ignoreList)
    table.insert(currentIgnoreList, part)

	local character = player.Character
	if character then --ignore player to reduce mess up in math
		for _, child in character:GetDescendants() do
			if child:IsA("BasePart") then
				table.insert(currentIgnoreList, child)
			end
		end
	end

	performRaycast(part.Position, camera.CFrame.Position, hitsToCamera, currentIgnoreList)
	performRaycast(camera.CFrame.Position, part.Position, hitsFromCamera, currentIgnoreList)

1 Like

It appears to have nearly doubled my FPS. Wouldn’t say it is fixed but it is a lot better. Thank you

If you would like I could improve the code a little more to hopefully increase your performance

I found a fix using collectionservice. Thank you for the help.

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