I have a touched event that fires when a character part touches it. The event makes all parts within that character forcefield material. it lags a ton. Any way to fix this?
incineratorZone.Touched:Connect(function(hit)
-- Use BasePart check to cover all part-like objects
if hit:IsA("BasePart") and not touchedparts[hit] then
print(hit)
-- Immediately mark as processed to prevent race conditions
touchedparts[hit] = true
task.spawn(function()
-- Visual effects
hit.Material = Enum.Material.ForceField
hit.Color = Color3.fromRGB(252, 0, 255)
-- Non-blocking delay
task.wait(0.3)
-- Cleanup
hit:Destroy()
touchedparts[hit] = nil
end)
end
end)
Well⌠in my case it does because it touches all the player body parts. The reason i do this is because i want it to be gradualâas each part touches the incinerator zone i want it to become forcefield material. In any case, I am asking for help to make it less laggy. not what the script does.
I guess since all the parts of the character call the function itâs gonna lag
actually there might be a lot less lag if you got rid of the print statement
It would be helpful if you elaborated on what you mean by lag, do the frames drop? Does the ping spike? What exactly is happening? Why do you think itâs the materialâs fault?
Frames drop a ton. I have found a temporary solution by adding a wait(0.1) so that the materials change on seperate frames. Are forcefield materials always so unperformant?
Three different attempts combined at smoothing this out.
local incineratorZone = script.Parent
local touchedCharacters = {}
incineratorZone.Touched:Connect(function(hit)
if not hit:IsA("BasePart") then return end
local character = hit.Parent
if character and not touchedCharacters[character] then
touchedCharacters[character] = true
task.spawn(function()
for _, part in ipairs(character:GetChildren()) do
if part:IsA("BasePart") then
part.Material = Enum.Material.ForceField
part.Color = Color3.fromRGB(252, 0, 255)
end
end
task.wait(0.3)
if character then
character:Destroy()
end
touchedCharacters[character] = nil
end)
end
end)
This is great! However, as I said I want it to be gradualâwhen each part touches it, it turns into the forcefield material. I would also like it to only apply to the touching parts and not the whole char.
I knew you would come back with that ⌠Iâm looking for a solid base to work from. Iâm sure you can implement what you want to that. The biggest thing here is a controlled de-bounce. Can not have that firing at will ⌠Swapping the material should not be a problem at all ⌠Over calling that will.
Checking if character here is pointless because the variable is never assigned-to after it has already been checked by the first if. character will always refer to the Character model, even if it is :Destroyâd, because the variable is holding a reference to it that prevents it from actually being deleted. Values cannot spontaneously become false or nil unless the code explicitly sets them as such, thus the check will never fail as that is all that is needed for the condition to pass.
This is a common way to stop a script fail error. When youâre waiting there is always a chance the player could just exit the game. Script errors on the next line and never recovers.
As far as the task.spawn there is a whole function after that. As I said this is a multiple attempt at stopping the problem. Take from it what works for youâŚ
If you have something to help with this question why donât you post your attempt.
Why even comment on my post âŚ
You can try this but if it isnât up to your standards idk what is.
local touchedParts = {}
incineratorZone.Touched:Connect(function(Hit: BasePart)
if not Hit:IsA("BasePart") then return end --// if "Hit" isn't a BasePart (Part, UnionOp, Mesh) then return
if touchedParts[Hit] then return end --// if "Hit" is already in "touchedParts" then return, code for Hit object has already been ran.
if not Hit.Parent or not Hit.Parent:FindFirstChildOfClass("Humanoid") then return end --// if "Hit" doesn't have a parent (it should but it had a type checking issue so..)
-- or if Hit isn't a direct child of Character then return
touchedParts[Hit] = true
Hit.Material = Enum.Material.ForceField
Hit.Color = Color3.fromRGB(252, 0, 255)
task.delay(0.3, function() --// Waits 0.3 seconds then runs code in function
if not Hit.Parent then --// Checking to see if the parent is nil cause if the Hit is destroyed we still have the reference to the direct object but the Hit (should) be parented to nil.
touchedParts[Hit] = nil
return
end
Hit:Destroy()
touchedParts[Hit] = nil
end)
end)
Touched events are fired continuously, and print too many print statements will also lag out studio badly, especially with certain output window formatting options. You should logic in your touched handler so that it doesnât run any code on redundant touched events, and remove the print() call or move it to where it at least doesnât fire for every Touched event.
Forcefield material is probably a red herring, thereâs nothing particularly expensive about it, itâs just a shader trick.
You can debounce per part and do batch processing so instead of processing every touch event instantly, use a queue system.
local incineratorZone = script.Parent
local touchedparts = {}
local processingQueue = {}
local function processPart(hit)
if hit:IsA("BasePart") and not touchedparts[hit] then
touchedparts[hit] = true
task.spawn(function()
for i = 1, 5 do
if hit and hit.Parent then
hit.Material = Enum.Material.ForceField
hit.Color = Color3.new(1, 0, 1)
hit.Transparency = hit.Transparency + 0.2
end
task.wait(0.1)
end
if hit and hit.Parent then
hit.Transparency = 1
hit.CanCollide = false
hit.CanTouch = false
task.wait(1)
hit:Destroy()
end
touchedparts[hit] = nil
end)
end
end
incineratorZone.Touched:Connect(function(hit)
if hit:IsA("BasePart") and hit.Parent and hit.Parent:FindFirstChild("Humanoid") then
table.insert(processingQueue, hit)
end
end)
task.spawn(function()
while true do
if #processingQueue > 0 then
local hit = table.remove(processingQueue, 1)
if hit then
processPart(hit)
end
end
task.wait(0.1)
end
end)
So no lag spikes and your Gradual effect still remains etcâŚ
An error cannot occur here because character can never become nil within the scope, even if the Player leaves the game ÂŻ\_(ă)_/ÂŻ
Itâs just a nitpick on code quality. I am just informing you that you can save time and remove a few lines of code that do nothing, it is for your and other peopleâs benefit to know that the check is not necessary.
Ya I just guess on these and spit it out. I need something to test with to be sure. Just a few possible fixes⌠He will have to test this stuff for himself.
âcharacter can never become nil within the scopeâ Youâre correct here.
The print might actually be causing most of the lag since when the character walks into the zone, it might have to print out a lot of parts all at once from the character.
When I remove that, my machine does not lag. If it truly is the material, then thereâs nothing to be done other than not use it.
Edit: So apparently, I missed reading some previous messages because there were several other people who mentioned the print being the issue before I did. If I would have realized that I wouldnât have posted this, mb. If it is the print, give the solution to the first person who pointed it out. keeping this up to reemphasize the print is probably the issue.
Yeah the print is whatâs going to do the most performance when testing in studio, if this post did anything it just proved theirs always more than 1 solution to a problem.
If it will error (it wonât in this case), it will stop execution of that thread only, and in case of connected function, it will stop only that fired connection once, and wonât impact further executions.