While Loop Help

Hello! The problem is that when I touch a part and then quickly stop touching it a few times in a row, the lighting.FogEnd value breaks — it gets stuck at a value, for example, 200, and then keeps adding 50 and removing 50 repeatedly. How can I fix this? Also, can someone suggest how it’s better make this system? Because I want less code

local Players = game:GetService("Players")
local locationFolder = game.Workspace:WaitForChild("Map"):WaitForChild("BetweenPOOandEND"):WaitForChild("DarkLocation")
local DarnkessTrigger = locationFolder:WaitForChild("AmbientTrigger"):WaitForChild("Trigger")

local playersInZone = {}

local function getPlayerFromPart(part)
	local character = part:FindFirstAncestorOfClass("Model")
	if character then
		return Players:GetPlayerFromCharacter(character)
	end
	return nil
end

local lighting = game.Lighting
local basicFogValue = 1000
local darknessFogValue = 50

local function startDarkness()
	while lighting.FogEnd > darknessFogValue do
		lighting.FogEnd = math.max(darknessFogValue, lighting.FogEnd - 50)
		task.wait(0.075)
	end
end

local function endDarkness()
	while lighting.FogEnd < basicFogValue do
		lighting.FogEnd = math.min(basicFogValue, lighting.FogEnd + 50)
		task.wait(0.075)
	end
end


DarnkessTrigger.Touched:Connect(function(part)
	local player = getPlayerFromPart(part)
	if player and not playersInZone[player] then
		playersInZone[player] = true
		print("dark activated for", player.Name)
		startDarkness()
	end
end)

DarnkessTrigger.TouchEnded:Connect(function(part)
	local player = getPlayerFromPart(part)
	if player and playersInZone[player] then
		task.delay(0.1, function()
			local character = player.Character
			if character and playersInZone[player] then
				for _, part in ipairs(character:GetDescendants()) do
					if part:IsA("BasePart") then
						local touchingParts = part:GetTouchingParts()
						for _, touching in ipairs(touchingParts) do
							if touching == DarnkessTrigger then
								return
							end
						end
					end
				end
				
				playersInZone[player] = nil
				endDarkness()
				print("touch ended for", player.Name)
			end
		end)
	end
end)

This is a mass debouce technique. EndTouch is pretty much unusable also.

local Players = game:GetService("Players")
local trigger = workspace.Map.BetweenPOOandEND.DarkLocation.AmbientTrigger.Trigger
local lighting = game.Lighting
local basicFog, darkFog = 1000, 50
local db = {}

local function getPlayer(part)
	local c = part:FindFirstAncestorOfClass("Model")
	return c and Players:GetPlayerFromCharacter(c)
end

local function fadeFog(to)
	while lighting.FogEnd ~= to do
		lighting.FogEnd = to > lighting.FogEnd and math.min(to, lighting.FogEnd + 50) or math.max(to, lighting.FogEnd - 50)
		task.wait(0.075)
	end
end

trigger.Touched:Connect(function(part)
	local plr = getPlayer(part)
	if not plr then return end
	if not db[plr] then
		db[plr] = true
		if next(db) and lighting.FogEnd ~= darkFog then fadeFog(darkFog) end
		return
	end
	task.delay(0.2, function()
		for _, p in ipairs(plr.Character:GetDescendants()) do
			if p:IsA("BasePart") then
				for _, t in ipairs(p:GetTouchingParts()) do
					if t == trigger then return end
				end
			end
		end
		db[plr] = nil
		if not next(db) then fadeFog(basicFog) end
	end)
end)

May have to work with the timing here.
Version 2

Once player not touchin the trigger anymore the fadeFog not going up. Maybe it’s better to use Region3?

It’s not your logic, it’s that it will fire many times. If the player stops on the trigger it will for sure.
Endtouch isn’t very good out of the box, and sure isn’t trustworthy. Also you didn’t use a debounce technique at all. Really going to fire a lot like that.

I mean, I tried to use your script, but when the player removing from table the fogEnd value not going up to basicFog Value

This is better than TouchEnded and can be trusted.

With these, when I really want an ended, I’ll put a block out there, get the dimensions, and set up a Region3 zone for this. Or I’ll use two touched parts with a bool.Value or in the same script.. done it a few ways, just not with TouchEnded.

Alright, thanks. I’ll try to learn how to use it