henlo
so i’m creating a sanity system (y’know, where you look at something and your sanity goes down and stuff? horror game stuff…)
i’ve been stuck at it for a while (i’m not particularly good at stuff where you have to regenerate a value or decrease it on conditions) and im sort of at a dead end.
What I want it to do:
If you look at a monster, denoted by IsFacing, call the sprint function
the sprint function will reduce your sanity as you look at it.
the moment you stop looking, your sanity will stop reducing too.
if you aren’t looking at a monster, call the regen function
in the regen function, if you haven’t looked at it for at least 2 seconds, your sanity will begin to regenarate.
cancel this process if at any point you look at a monster.
-- services
local TS = game:GetService("TweenService")
local UIS = game:GetService("UserInputService")
local RS = game:GetService("RunService")
local player = game:GetService("Players").LocalPlayer
local char = player.Character or player.CharacterAdded:Wait()
local hum = char:WaitForChild("Humanoid")
-- UI
local plrgui = player:WaitForChild("PlayerGui")
local sansys = plrgui:WaitForChild("SanitySystem")
local backdrop = sansys:WaitForChild("Backdrop")
local cover = backdrop.Cover
-- sanity variables
local maxsanity = 400
local sanity = maxsanity
local sancost = 2
local sanregen = 2
sanity = math.clamp(sanity, 0, maxsanity)
-- keeping track of the regeneration thread counts
local regenerationThreadCount = 0
-- last time when they see a monster
lastseentime = 0
local function updatesan()
sanity = math.clamp(sanity, 0, maxsanity)
cover:TweenSize(
UDim2.new(0.7, 0, (sanity/maxsanity) * 0.969, 0),
Enum.EasingDirection.InOut,
Enum.EasingStyle.Linear,
0
)
end
local isseen = false
local function seen(isFacingMonster)
isseen = true
lastseentime = tick()
sanity -= sancost
updatesan()
task.wait(0.05)
end
local function regen()
task.wait(2)
regenerationThreadCount += 1
local currentThreadCount = regenerationThreadCount
sancost = 0
for i = sanity, maxsanity, sanregen do
sanity = i
i += sanregen
sanity = i
updatesan()
task.wait(0.05)
if regenerationThreadCount ~= currentThreadCount then
break
end
end
end
RS.RenderStepped:Connect(function()
coroutine.wrap(function()
for _, part in game:GetService("Workspace").Monsters:GetChildren() do
local cam = game:GetService("Workspace").CurrentCamera
local Angle = 0.7
local unit = ((part.Position - char.Head.Position) * Vector3.new(1,0,1)).Unit
local HeadLookVec = char.Head.CFrame.LookVector * Vector3.new(1,0,1)
local IsFacing = HeadLookVec:Dot(unit) > Angle
if IsFacing then
lastseentime = tick()
sanregen = 0
sancost = 2
seen(IsFacing)
else
sanregen = 2
sancost = 0
regen(IsFacing)
end
end
end)()
end)
Hello! It seems like you are on the right track with your sanity system. Here are a few suggestions that may help you:
Separate the functions for increasing and decreasing sanity: It might be easier to handle the increase and decrease of sanity in separate functions. For example, you could have a DecreaseSanity function that is called when the player looks at a monster and a IncreaseSanity function that is called when the player is not looking at a monster.
Use a debounce to prevent multiple calls: To prevent multiple calls to the same function, you can use a debounce. For example, when the player looks at a monster, you can use a debounce to ensure that the DecreaseSanity function is only called once.
Use a timer to track how long the player has been looking at a monster: You can use a timer to track how long the player has been looking at a monster. Once the timer reaches a certain threshold (e.g., 2 seconds), you can start decreasing the player’s sanity.
Use a coroutine to handle the regeneration of sanity: Instead of calling the Regen function continuously, you can use a coroutine to handle the regeneration of sanity. This way, the function will only be called when necessary.
Here’s an example implementation that incorporates these suggestions:
-- services
local TS = game:GetService("TweenService")
local UIS = game:GetService("UserInputService")
local RS = game:GetService("RunService")
local player = game:GetService("Players").LocalPlayer
local char = player.Character or player.CharacterAdded:Wait()
local hum = char:WaitForChild("Humanoid")
-- UI
local plrgui = player:WaitForChild("PlayerGui")
local sansys = plrgui:WaitForChild("SanitySystem")
local backdrop = sansys:WaitForChild("Backdrop")
local cover = backdrop.Cover
-- sanity variables
local maxsanity = 400
local sanity = maxsanity
local sancost = 2
local sanregen = 2
sanity = math.clamp(sanity, 0, maxsanity)
-- keeping track of the regeneration thread counts
local regenerationThreadCount = 0
-- last time when they see a monster
lastseentime = 0
-- debounce to prevent multiple calls
local debounce = false
local function DecreaseSanity()
if debounce then return end
debounce = true
sanity -= sancost
updatesan()
end
local function IncreaseSanity()
debounce = false
sanregen = 2
sancost = 0
end
local function updatesan()
sanity = math.clamp(sanity, 0, maxsanity)
cover:TweenSize(
UDim2.new(0.7, 0, (sanity/maxsanity) * 0.969, 0),
Enum.EasingDirection.InOut,
Enum.EasingStyle.Linear,
0
)
end
local function regen()
task.wait(2)
regenerationThreadCount += 1
local currentThreadCount = regenerationThreadCount
sancost = 0
for i = sanity, maxsanity, sanregen do
sanity = i
i += sanregen
sanity = i
updatesan()
task.wait(0.05)
if regenerationThreadCount ~= currentThreadCount then
break
end
end
end
local function HandleSanity()
for _, part in game:GetService("Workspace").Monsters:GetChildren() do
local cam = game:GetService