Ideal way to detect if player is near specific parts

What would be the best way to detect if the player is near a specific type of part, like ones in a folder for example, i have thought about running the script for each part independently, and making specific zones near the parts, but i dont know whats the easiest and best way to do it?
This is the script i’ve been using so far, because i only have one part, it changes the transparency of the selectionbox inside:

local player = game.Players.LocalPlayer
local part = workspace.Doors.d1
local SB = part.SelectionBox
local triggerDistance = 10
local tweenService = game:GetService("TweenService")
local runService = game:GetService("RunService")

local transparencyTweenInfo = TweenInfo.new(
	0.2,
	Enum.EasingStyle.Linear,
	Enum.EasingDirection.InOut
)

local transparencyTween = tweenService:Create(
	SB,
	transparencyTweenInfo,
	{ Transparency = 0 }
)

local reverseTween = tweenService:Create(
	SB,
	transparencyTweenInfo,
	{ Transparency = 1 }
)

local isTweenPlaying = false

local function calculateDistance()
	local partPosition = part.Position
	local playerPosition = player.Character and player.Character:FindFirstChild("HumanoidRootPart") and player.Character.HumanoidRootPart.Position

	if partPosition and playerPosition then
		return (partPosition - playerPosition).Magnitude
	else
		return math.huge
	end
end

local function updateTransparency()
	local distance = calculateDistance()

	if distance <= triggerDistance and part.Transparency == 0 then
		if isTweenPlaying == false then
			reverseTween:Cancel()
			transparencyTween:Play()
			isTweenPlaying = true
			wait(0.2)
			isTweenPlaying = false
		end
	elseif distance > triggerDistance then 
		if isTweenPlaying == false then
			transparencyTween:Cancel() -- BUGFIX #1
			reverseTween:Play()
			isTweenPlaying = true
			wait(0.2)
			isTweenPlaying = false
		end
	end
end

local function onRenderStep()
	updateTransparency()
end

runService.RenderStepped:Connect(onRenderStep)

EDIT: I used collectionservice since its easier to manage, worked first try like a charm.

1 Like

Does it have to be done every RenderStepped? Could it be done every .1 second or so?

You should probably check the distance in the calculateDistance function every RenderStepped (or whatever time frame) and then check to see if distance is <= triggerDistance, then fire the updateTransparency function to run the tweens. This would keep updateTransparency from firing when it isn’t needed.

to add on to that: If the specific parts are stationary, you could just detect it every time the character moves

i put it in a loop instead, but your comment helped, thanks!

Yeah, that’s basically what calling your runservice.RenderStepped:Connect(onRenderStep) function was doing.

Did you need to have it called every step? How often does it really need to check how close a player is to the Parts?
If changing the transparency isn’t really that critical at exactly 10 studs you may be able to use .1 seconds. Considering a player walkspeed is 16 studs/second if they were 10.05 studs away travelling at full walkspeed then the transparence tween would start when they were actually 1.6 studs less than 10 studs (they’d have walked that distance it .1 second) so it would start tweening at 8.4 studs instead. If you need it to be more precise then you could do it every .05 seconds which would equal 9.2 studs away.
That means that even at a task.wait() at 60 frames per second (.01667 seconds) the player would be .267 studs closer than 10 studs (9.73 studs)

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