Sanity System doesn't work?

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:
  1. 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.
  1. 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.
Video + what ends up happening:

untitled horror game framework testing - Roblox Studio 2023-03-10 18-26-58
As you can see, it looks like it jitters and is very inconsistent too. Sometimes it waits 2 seconds before regenerating, other times it doesn’t.

Code:
-- 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)

any help would be greatly appreciated!11! :smiley:

here is extra smiley face for good luck :smiley:

ok no worries now cause its ok now yes.

Hello! It seems like you are on the right track with your sanity system. Here are a few suggestions that may help you:

  1. 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.
  2. 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.
  3. 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.
  4. 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

no thank you, im alright.

This text will be blurred

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.