Script Spams Output and Lags Game

Hello, I am wondering what I can do to make this script perform better so it won’t slow the game down when running.

Plr = game.Players.LocalPlayer
Char = Plr.Character or Plr.CharacterAdded:Wait()
Trigger = workspace.Ambients.LightingTriggers.Haunt3
MagX = Trigger.Size.X / 2

while wait() do
	if (Trigger.Position - Char.HumanoidRootPart.Position).magnitude < MagX then
		tweenService:Create(lighting, TweenInfo.new(0.5), zoneLighting):Play()
		print("player entered zone")
	else -- [[This is where i believe the code causes performance issues]]
		tweenService:Create(lighting, TweenInfo.new(0.5), defaultLighting):Play()
		print("exited zone")
	end
end

You should store the last in/out status and only when the current status doesn’t equal the last status, play the tween

local last = false -- when last is false, they weren't in the zone for the last iteration, when it's true, they were

while true do
    if (Trigger.Position - Char.HumanoidRootPart.Position).magnitude < MagX and not last then -- they weren't in the zone for the last iteration so we can play the tween
        tweenService:Create(lighting, TweenInfo.new(0.5), zoneLighting):Play()
        last = true
    elseif last then -- they were in the last time, so play the exit tween
        tweenService:Create(lighting, TweenInfo.new(0.5), defaultLighting):Play()
        last = false
    end
    task.wait()
end

Tween:Play() doesn’t yield, it means you’re repeatedly triggering the same tween each ~0.03 second.

I got this in the Output

HumanoidRootPart is not a valid member of Model “Workspace.[redacted]”

You should use :WaitForChild instead of trying to index it with periods.

It’s around 0.017 seconds but that is intentional, you can increase or decrease the amount of checks by adding an argument to task.wait().

I added :WaitForChild and ended up with Attempt to Index Nil

Okay, then you should use player.Character or player.CharacterAdded:Wait() for your character variable as well as waitforchild.

It does not seem to do anything when going through the brick.

Plr = game.Players.LocalPlayer
Char = Plr.Character
Trigger = workspace.Ambients.LightingTriggers.Haunt3
MagX = Trigger.Size.X / 2

local last = false -- when last is false, they weren't in the zone for the last iteration, when it's true, they were

while true do
	wait()
	if not Plr then
		return
	end

	if Char and Char.PrimaryPart then
		if (Trigger.Position - Char.PrimaryPart.Position).magnitude < MagX and not last then -- they weren't in the zone for the last iteration so we can play the tween
			tweenService:Create(lighting, TweenInfo.new(0.5), zoneLighting):Play()
			last = true
		elseif last then -- they were in the last time, so play the exit tween
			tweenService:Create(lighting, TweenInfo.new(0.5), defaultLighting):Play()
			last = false
		end
		task.wait()
	end
end

local char = plr.Character or plr.CharacterAdded:Wait()

Im not sure whats happening, but I suspect the script does not know what the player is.

local plr = game.Players.LocalPlayer
local char = plr.Character or plr.CharacterAdded:Wait()
local Trigger = workspace.Ambients.LightingTriggers.Haunt3
local MagX = Trigger.Size.X / 2

local last = false -- when last is false, they weren't in the zone for the last iteration, when it's true, they were

while true do
	
wait()
		if (Trigger.Position - char.PrimaryPart.Position).magnitude < MagX and not last then -- they weren't in the zone for the last iteration so we can play the tween
			tweenService:Create(lighting, TweenInfo.new(0.5), zoneLighting):Play()
			last = true
		elseif last then -- they were in the last time, so play the exit tween
			tweenService:Create(lighting, TweenInfo.new(0.5), defaultLighting):Play()
			last = false
		end
		task.wait()
	end

Is this the full script? If not, could you post it? Any output errors?

Here is the full script. It’s just a LocalScript in StarterPlayerScripts.

local lighting = game:GetService("Lighting")
local tweenService = game:GetService("TweenService")


local defaultLighting = {
	FogColor = lighting.FogColor,
	FogStart = lighting.FogStart,
	FogEnd = lighting.FogEnd,
	ClockTime = lighting.ClockTime,
}


local zoneLighting = {
	FogColor = lighting.FogColor,
	FogStart = 20,
	FogEnd = 200,
	ClockTime = 0,
}

local plr = game.Players.LocalPlayer
local char = plr.Character or plr.CharacterAdded:Wait()
local Trigger = workspace.Ambients.LightingTriggers.Haunt3
local MagX = Trigger.Size.X / 2

local last = false -- when last is false, they weren't in the zone for the last iteration, when it's true, they were

while true do

	wait()
	if (Trigger.Position - char.PrimaryPart.Position).magnitude < MagX and not last then -- they weren't in the zone for the last iteration so we can play the tween
		tweenService:Create(lighting, TweenInfo.new(0.5), zoneLighting):Play()
		last = true
	elseif last then -- they were in the last time, so play the exit tween
		tweenService:Create(lighting, TweenInfo.new(0.5), defaultLighting):Play()
		last = false
	end
	task.wait()
end

Ohhh I see, that’s probably because you’re not handling when the player respawns. Try adding this somewhere in the script before the loop.

plr.CharacterAdded:Connect(function(newCharacter)
    char = newCharacter
end)

Then in your loop add an if-statement to check if char.PrimaryPart exists, if it doesn’t, the character doesn’t exist.

Sorry for the late response, I do not want the triggers to loop, I would like it to stay only while the player is inside the part, and stop when the player leaves it, instead of infinitly looping.