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