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