How to make detection go down

local DISTANCE = 30
local Players = game:GetService("Players")
local origin = script.Parent.Head 
local detection = 0 

local function detectionUp(player)
	if player.PlayerGui.ScreenGui:FindFirstChild("DetectionLabel") then
		detection += 1
		player.PlayerGui.ScreenGui.DetectionLabel.Visible = true
		player.PlayerGui.ScreenGui.DetectionLabel.Text = detection .. "%"
	end
end



while wait() do
	local ray = Ray.new(origin.Position, origin.CFrame.lookVector * DISTANCE)
	local hit = workspace:FindPartOnRay(ray, origin.Parent)
	
	for _, player in pairs(Players:GetPlayers()) do
		if hit then  

			if player.Character and player.Character:IsAncestorOf(hit) then 
				print("I see " .. player.Name)
				detectionUp(player)
			end
	    end
	end
end

I have this script so when player is in NPC’s view, detection goes up. I also need so detection goes down after some time. How can I implement that?

5 Likes

use RunService.Heartbeat to update the game logic every tick using delta time.
also dont use Ray.new() its deprecated, use WorldRoot:RayCast() or sumthign

2 Likes

Well thanks, but that does not answer my main question

Well your request mainly depends on how you want to implement it. You really shouldn’t ask for people to implement features in your code for you.

1 Like

About first part, I want for it to go down when player is not in NPC’s view for 5 seconds. About second part, I am ask how I can implement it.

1 Like

Well you kinda just answered your own question lol.

1 Like

? What do you mean? I dont understand ya

1 Like

you said you wanted it implemented in a way where you want it to go down when the player is not in the npc’s view for 5 seconds and then you also said you are asking how to implement it when you just said how to.

@CCTVStudios gave you a great answer. Before the main code starts, you do:

local LastTime = tick() -- tick is the number of time that has passed.

Then instead of a while wait() loop you use RunService.Heartbeat.
You will make a new variable called CurrentTime and set it to tick()
Then you can do:

if CurrentTime - LastTime >= 5 then --5 is the number of seconds.

After that, you set the LastTime variable to CurrentTime and run your code which makes detection go down.

I hope that helps you out!

Edit: By the way use task.wait() instead of wait() in future code, it is more optimized and faster. And also if you were to use the tick() method on a client, there can be small delays if the player has < 60 FPS and there is not much you can do about it to my knowledge.

1 Like

I dont really understand what he is trying to achieve, but if he wants to make a value go down overtime he should be stepping all his game logic through Heartbeat, You dont even need to check if 5 seconds passed, you could just use delta time and multiply it by the speed its supposed to go down

local RunService = game:GetService("RunService")

local DetectionLoweringSpeed = 0.2 -- unit per second
local Detection = 100 -- idk imma assume it starts at 100

RunService.Heartbeat:Connect(function(DeltaTime)
       local CalculatedDetection = Detection
       CalculatedDetection += DetectionLoweringSpeed * DeltaTime
       
       if CalculatedDetection < 0 then
              CalculatedDetection = 0
       end
       Detection = CalculatedDetection
end)

Using this method is way better because if you force the program to not step the game logic until that time happens can cause low tickrates to mess stuff up, Lets put an unrealistic scenario:

The machine lags and the next step happens after 10 seconds, the game is gonna check if 5 seconds passed, and step it once then wait for the next step. You can see already how that is terrible since the other 5 seconds got completely ignored.

Meanwhile this method doesnt cares how much time passed, it will step it accordingly

1 Like

You are correct but in this case, the person who created the topic wants to run it when the player is not in the NPC’s view for 5 seconds. And if I didn’t get it wrong that means that the person wants it to go down after 5 seconds passed. But I may have understood it wrong.

1 Like

Yes, you are right. It should go down after 5 seconds passed of NPC not being able to see player

Changed code to this (I dont know did I do this right, I wrote those as I understood):

local DISTANCE = 30
local Players = game:GetService("Players")
local origin = script.Parent.Head 
local detection = 0 
local LastTime = tick()

local function detectionUp(player)
	if player.PlayerGui.ScreenGui:FindFirstChild("DetectionLabel") then
		player.PlayerGui.ScreenGui.DetectionLabel.Visible = true
		if detection ~= 100 then
			detection+=1
			player.PlayerGui.ScreenGui.DetectionLabel.Text = detection .. "%"
		end
	end
end

local function detectionDown(player)
	if player.PlayerGui.ScreenGui:FindFirstChild("DetectionLabel") then
		if detection ~= 0 then
			detection-=1
			player.PlayerGui.ScreenGui.DetectionLabel.Text = detection .. "%"
		end
		if detection == 0 then
			player.PlayerGui.ScreenGui.DetectionLabel.Visible = false
		end
	end
end




game:GetService("RunService").Heartbeat:Connect(function()
	local CurrentTime = tick()
	local ray = Ray.new(origin.Position, origin.CFrame.lookVector * DISTANCE)
	local hit = workspace:FindPartOnRay(ray, origin.Parent)

	for _, player in pairs(Players:GetPlayers()) do
		if hit then  

			if player.Character and player.Character:IsAncestorOf(hit) then 
				print("I see " .. player.Name)
				if CurrentTime - LastTime >= 5 then
					detectionDown(player)
				else
					detectionUp(player)
				end
				
			end
		end
	end
end)

Now when player is in NPC’s view, DetectionLabel doesnt show up

This code technically works but it will only work once. So whenever you want to start checking it again (for example when the NPC looks at the player again) you have to set LastTime to tick() again or else CurrentTime - LastTime will always be greater than 5 meaning detectionDown will run forever.

1 Like
local DISTANCE = 30
local Players = game:GetService("Players")
local origin = script.Parent.Head 
local detection = 0 
local LastTime = tick()

local function detectionUp(player)
	if player.PlayerGui.ScreenGui:FindFirstChild("DetectionLabel") then
		player.PlayerGui.ScreenGui.DetectionLabel.Visible = true
		if detection ~= 100 then
			detection+=1
			player.PlayerGui.ScreenGui.DetectionLabel.Text = detection .. "%"
		end
	end
end

local function detectionDown(player)
	if player.PlayerGui.ScreenGui:FindFirstChild("DetectionLabel") then
		if detection ~= 0 then
			detection-=1
			player.PlayerGui.ScreenGui.DetectionLabel.Text = detection .. "%"
		end
		if detection == 0 then
			player.PlayerGui.ScreenGui.DetectionLabel.Visible = false
		end
	end
end




game:GetService("RunService").Heartbeat:Connect(function()
	local CurrentTime = tick()
	local ray = Ray.new(origin.Position, origin.CFrame.lookVector * DISTANCE)
	local hit = workspace:FindPartOnRay(ray, origin.Parent)

	for _, player in pairs(Players:GetPlayers()) do
		if hit then  

			if player.Character and player.Character:IsAncestorOf(hit) then 
				print("I see " .. player.Name)
				if CurrentTime - LastTime >= 5 then
					detectionDown(player)
					LastTime = CurrentTime
				else
					detectionUp(player)
					LastTime = CurrentTime
				end
				
			end
		end
	end
end)

It goes up but never goes down

I saw that function isnt even getting called after those 5 seconds