I'm trying to make a hiding system with a time limit

I’m trying to make a closet hiding system that kills you if you hide for too long

the while loop doesn’t stop if I exit the closet

here is my script

local replicatedstorage = game:GetService("ReplicatedStorage")
local changecamevent = replicatedstorage.Events:WaitForChild("changecamera")
local resetcamevent = replicatedstorage.Events:WaitForChild("resetcamera")
local DisableControlsevent = replicatedstorage.Events:WaitForChild("DisableControls")
local enablecontrolsevent = replicatedstorage.Events:WaitForChild("enablecontrols")
local userinputservice = game:GetService("UserInputService")

local plr = game:GetService("Players").PlayerAdded:Wait()

local timeincloset = 0
local colorcorrection = game:GetService("Lighting"):WaitForChild("ColorCorrection")

local debounce = false
local cd = 2.5

local promt = script.Parent.ProximityPrompt
local door1 = script.Parent.Parent.door1
local door2 = script.Parent.Parent.door2
local wtp = script.Parent.Parent.wtp
local wtp2 = script.Parent.Parent.wtp2

local cam1 = script.Parent.Parent.cam1
local cam2 = script.Parent.Parent.cam2

local opensound = script["Closet Open"]
opensound.Volume = 2
local closesound = script["Close Closet Door"]
closesound.Volume = 1

local hiding = plr:WaitForChild("Hiding")
hiding.Value = false

promt.Triggered:Connect(function()
	if hiding.Value == false then
		if debounce == false then
			opensound:Play()
			DisableControlsevent:FireClient(plr)
			debounce = true
			promt.Enabled = false
			hiding.Value = true
			door1.CanCollide = false
			door2.CanCollide = false
			changecamevent:FireClient(plr, cam1)
			wait(0.5)
			plr.Character.Humanoid:MoveTo(wtp.Position)
			wait(0.5)
			plr.Character.Humanoid.WalkSpeed = 0
			for i, v in pairs(plr.Character:GetDescendants()) do
				if v:IsA("BasePart") or v:IsA("Decal") then
					v.Transparency = 1
				end
			end
			changecamevent:FireClient(plr, cam2)
			door1.CanCollide = true
			door2.CanCollide = true
			closesound:Play()
			promt.ActionText = "Exit"
			promt.Enabled = true
			while true do
				wait()
				while timeincloset < 5 do
					wait(1)
					timeincloset += 1
					colorcorrection.Saturation -= 0.15
				end
				while timeincloset == 4 do
					wait(1)
					timeincloset += 1
				end
				if timeincloset == 5 then
					colorcorrection.Saturation = 0
					colorcorrection.TintColor = Color3.new(1, 0, 0)
				end
				if colorcorrection.TintColor == Color3.new(1, 0, 0) then
					timeincloset = 0
					hiding.Value = false
					debounce = false
					wait(1)
					plr.Character.Humanoid.Health = 0
					colorcorrection.TintColor = Color3.new(1, 1, 1)
					resetcamevent:FireClient(plr)
					promt.ActionText = "Hide"
					promt.Enabled = true
					enablecontrolsevent:FireClient(plr)
					break
				end
			end
		end
	end
end)

promt.Triggered:Connect(function()
	if hiding.Value == true then
		timeincloset = 0
		opensound:Play()
		hiding.Value = false
		promt.Enabled = false
		door1.CanCollide = false
		door2.CanCollide = false
		plr.Character.Humanoid.WalkSpeed = 16
		wait(0.1)
		for i, v in pairs(plr.Character:GetDescendants()) do
			if v:IsA("BasePart") or v:IsA("Decal") then
				v.Transparency = 0
			end
			if v.Name == "HumanoidRootPart" then
				v.Transparency = 1
			end
		end
		plr.Character.Humanoid:MoveTo(wtp2.Position)
		resetcamevent:FireClient(plr)
		wait(0.5)
		closesound:Play()
		door1.CanCollide = true
		door2.CanCollide = true
		enablecontrolsevent:FireClient(plr)
		wait(cd)
		debounce = false
		promt.ActionText = "Hide"
		promt.Enabled = true
	end
end)

this is the part of the script i need help with

while true do
				wait()
				while timeincloset < 5 do
					wait(1)
					timeincloset += 1
					colorcorrection.Saturation -= 0.15
				end
				while timeincloset == 4 do
					wait(1)
					timeincloset += 1
				end
				if timeincloset == 5 then
					colorcorrection.Saturation = 0
					colorcorrection.TintColor = Color3.new(1, 0, 0)
				end
				if colorcorrection.TintColor == Color3.new(1, 0, 0) then
					timeincloset = 0
					hiding.Value = false
					debounce = false
					wait(1)
					plr.Character.Humanoid.Health = 0
					colorcorrection.TintColor = Color3.new(1, 1, 1)
					resetcamevent:FireClient(plr)
					promt.ActionText = "Hide"
					promt.Enabled = true
					enablecontrolsevent:FireClient(plr)
					break
				end
			end

I’ve tried moving the while loop but it just doesn’t work at all unless its where i put it

1 Like

when you do a while loop it will constantly loop until it is broken out of or the base case is met. you have a while true do loop then immediately follow up with another while loop which’ll keep iterating until timeincloset is greater than 5.

then immediately you have another while loop waiting for timeincloset to equate to 4, which it never will because the previously loop made it 6 and you never reset it back to 0.

I reset it to 0 on this line here

yes but thats on trigger, if you’re trying to force someone out and they do not trigger the prompt again, that triggered event won’t set it to 0. so your loop on the prompt event to enter will never end.

so what should I do to fix it?

what i’d do is change the timeincloset loop to say while timeincloset < 4 since that’ll stop it once it reaches 5. also add prints to see if there’re any key points where it breaks or functions in a way you haven’t intended for.

its still not breaking the loop when I exit the closet

save the tick() of when you enter (outside the loop, god forbid you put it inside the loop) and check if the difference between the current tick() and the saved one is a certain number or respects a certain interval of numbers (>, <, ==, ~=)

What is the point of:

while timeincloset == 4 do
					wait(1)
					timeincloset += 1
				end

This is redundant as the first while… do loop should already reach the value of 5

how would I go about doing this

little example

local HideStart = 0

local function CoroutineBody()
      HideStart = tick()
      
      while something do
           if math.floor(tick() - HideStart) == 5 then -- just to be sure
                 -- do something
           end
      end
end

TriggeringEvent:Connect(function()
       coroutine.resume(coroutine.create(CoroutineBody))
end)

what does this line of code do

look at the last answer I sent…

I make a variable called HideStart that acts as a handle for our hide start time

tick() returns the time since UNIX time and we can make calculations between different tick() returns to handle time and stuff like that

basically when a TriggeringEvent (may be your proximityprompt being triggered) gets fired, assign hidestart to the current tick() value, then start a loop with whatever condition you want and check if the difference between tick() and the saved tick value (ofc math.floor) is a certain number. in this case you may want to use a routine just to make sure you don’t yield any code

it’s a coroutine or a sub-thread, it runs separately from the runtime and basically does stuff on its own without waiting for stuff that happened before it or making others wait

Out of curiosity, how would knowing the difference between the times help with the problem? (Sorry for the dumb question)

in your case it may be like

local HideStart = 0

local function ClosetHandler()
      HideStart = tick()

      while math.floor(tick() - HideStart) < Limit do
          task.wait()
          -- saturation code idk
      end
end

promt.Triggered:Connect(function()
       -- code you had before, maybe a little improved :)

      coroutine.resume(coroutine.create(ClosetHandler))
end)

cause it’s literally doing the job for you by not having to count time individually

1 Like

Oh I see, you would use tick instead of using wait

would I put this in the first Pront.Triggered function or on its own

you know you have two times A and B

B was taken a little before A

you know that A is a tick() value than B cause it was taken after B.

A - B is the difference between the two times

1 Like