Making a script where it plays function whenever certain NPC is out of range

Hello their users of devforum, once again. I have met a certain issue with a script where the function plays even when the NPC is inside the range of the block. I want it so that the function plays only when the NPC is outside of the range of the block. Though It still plays even when its inside. Any Ideas?
The script does not post any errors by the way.

local animobject = script.Parent:FindFirstChildOfClass("Animation")
local Seat = script.Parent.Parent

local SCP106 = game.Workspace.SCP106
local SCPDISTANCE = script.Parent.Parent.Parent.Range

Seat.Disabled = true

local anim = nil
--disconnects and stops the animation after someone gets up
Seat:GetPropertyChangedSignal("Occupant"):Connect(function()
	local occupant = Seat.Occupant
	if occupant == nil then -- if its empty (someone got up)
		if anim then
			anim:Stop()
			anim:Disconnect()
			anim = nil
		end
	end
end)

script.Parent.MouseClick:Connect(function(plr)
	if script.Parent.Parent.Occupant == nil then --if nobodys sitting
		local char = plr.Character
		if char then --checks if character exists
			local hum = char:FindFirstChildOfClass("Humanoid")
			if hum then -- checks if humanoid exists
				Seat:Sit(hum) --sits plr
				local animator = hum:FindFirstChildOfClass("Animator")
				if animator then --checks if animator exists
					anim = animator:LoadAnimation(animobject)
					anim:Play()
					
					SCPDISTANCE.Touched:Connect(function(hit)
						if hit.Parent.Name == "SCP106" then
							print("SCP-106 Is In Chamber")
						else
							script.Parent.Activator.ClickDetector.MouseClick:Connect(function()
								script.Parent.Activator.Sound:Play()
								hum.JumpPower = 0
								wait(70)
								script.Parent.Activator.Sound:Pause()
								hum.JumpPower = 50
								hum.Health = 0
							end)
						end
					end)		
				end
			end
		end
	end
end)

Is this the part that’s checking if it’s range? I can’t really tell where you check if they’re not in range

And is the function supposed to be the ClickDetector one?

yes scpdistance is the part checking range and the function is the clickdetector

1 Like

It’s still running even when the NPC is outside the range because you are connecting the function whenever the NPC is outside the range, but never disconnecting it (making it unable to run) once the NPC is inside

This is also causing a lot of useless and repeated connections (because Touched will run multiple times and in consequence bind it a lot) therefore I’d recommend moving the entire function outside of the scope and checking if the NPC is inside using spatial query

Code
local animobject = script.Parent:FindFirstChildOfClass("Animation")
local Seat = script.Parent.Parent

local SCP106 = game.Workspace.SCP106
local SCPDISTANCE = script.Parent.Parent.Parent.Range

Seat.Disabled = true

local anim = nil
--disconnects and stops the animation after someone gets up
Seat:GetPropertyChangedSignal("Occupant"):Connect(function()
	local occupant = Seat.Occupant
	if occupant == nil then -- if its empty (someone got up)
		if anim then
			anim:Stop()
			anim:Disconnect()
			anim = nil
		end
	end
end)

script.Parent.Activator.ClickDetector.MouseClick:Connect(function()
	for _, v in workspace:GetPartsInPart(workspace.SCPDISTANCE) do
		if v.Parent.Name == "SCP106" then
			print("SCP-106 Is In Chamber")
			return
		end
	end
	
	-- Probably find a way to get the humanoid in here, I'm not gonna bother too much, sorry.
	script.Parent.Activator.Sound:Play()
	hum.JumpPower = 0
	wait(70)
	script.Parent.Activator.Sound:Pause()
	hum.JumpPower = 50
	hum.Health = 0
end)

script.Parent.MouseClick:Connect(function(plr)
	if script.Parent.Parent.Occupant == nil then --if nobodys sitting
		local char = plr.Character
		if char then --checks if character exists
			local hum = char:FindFirstChildOfClass("Humanoid")
			if hum then -- checks if humanoid exists
				Seat:Sit(hum) --sits plr
				local animator = hum:FindFirstChildOfClass("Animator")
				if animator then --checks if animator exists
					anim = animator:LoadAnimation(animobject)
					anim:Play()
				end
			end
		end
	end
end)

Alternatively, you can disconnect the function

Code
local animobject = script.Parent:FindFirstChildOfClass("Animation")
local Seat = script.Parent.Parent

local SCP106 = game.Workspace.SCP106
local SCPDISTANCE = script.Parent.Parent.Parent.Range

Seat.Disabled = true

local anim = nil
--disconnects and stops the animation after someone gets up
Seat:GetPropertyChangedSignal("Occupant"):Connect(function()
	local occupant = Seat.Occupant
	if occupant == nil then -- if its empty (someone got up)
		if anim then
			anim:Stop()
			anim:Disconnect()
			anim = nil
		end
	end
end)

local clickDetectorConnection: RBXScriptConnection
script.Parent.MouseClick:Connect(function(plr)
	if script.Parent.Parent.Occupant == nil then --if nobodys sitting
		local char = plr.Character
		if char then --checks if character exists
			local hum = char:FindFirstChildOfClass("Humanoid")
			if hum then -- checks if humanoid exists
				Seat:Sit(hum) --sits plr
				local animator = hum:FindFirstChildOfClass("Animator")
				if animator then --checks if animator exists
					anim = animator:LoadAnimation(animobject)
					anim:Play()

					SCPDISTANCE.Touched:Connect(function(hit)
						if hit.Parent.Name == "SCP106" then
							print("SCP-106 Is In Chamber")

							if clickDetectorConnection then
								clickDetectorConnection:Disconnect()
							end
						else
							if not clickDetectorConnection then
								clickDetectorConnection = script.Parent.Activator.ClickDetector.MouseClick:Connect(function()
									script.Parent.Activator.Sound:Play()
									hum.JumpPower = 0
									wait(70)
									script.Parent.Activator.Sound:Pause()
									hum.JumpPower = 50
									hum.Health = 0
								end)
							end
						end
					end)		
				end
			end
		end
	end
end)
1 Like

Thanks man this really helped alot.

1 Like