How to change the part closest to the player properties

So I tried to make like multiple parts in a table and if one of those parts are in rage of the player then activate (do something) but I have no idea how to make it that the closest part to the player activates and not all the parts in range…

local runservice = game:GetService("RunService")

local player = game.Players.LocalPlayer
local inrange = false

local interactable_items = {
	game.Workspace.Toy1,
	game.Workspace.Toy2,
	game.Workspace.Toy3
}

local function distancecheck()
	local distance = 10
	local object
	
	for i, v in pairs(interactable_items) do
		if (v.Position - player.Character.HumanoidRootPart.Position).magnitude < distance then
			print("player in range")
			inrange = true 
			object = v
		end
	end
	return object
end

runservice.RenderStepped:Connect(function()
	local object = distancecheck()
	if object and inrange == true then
		object.Position = object.Position + Vector3.new(0, 5, 0) -- do something
	end
end)

When you loop through the objects, you should update distance to the parts that are within the 10 stud range. This way you will truly get the closest part instead of the last part that is within the range.

Also, it’s a bad practice to have the global variable inrange for a function you call to check distance, especially if you never turn to back to false. If object returns nil from your distancecheck() function, then it means no parts were in range and the inrange variable is obsolete.

Yeah I understand that but how do I do that? like how can I apply your method

You just update a variable…?


local function distancecheck()
	local distance = 10 -- min range
	local object
	
	for i, v in pairs(interactable_items) do
		local dist = (v.Position - player.Character.HumanoidRootPart.Position).magnitude
		if dist < distance then
			print("player in range")
			distance = dist -- update distance so only parts closer than this one can be selected
			object = v
		end
	end
	return object
end

And then remove all mention of inrange because it serves no purpose.

1 Like

I tryed something like that before and didn’t worked properly, like I tried to apply it again now but still not really working…

I updated the script to this:

local runservice = game:GetService("RunService")

local player = game.Players.LocalPlayer

local interactable_items = {
	game.Workspace.Toy1,
	game.Workspace.Toy2,
	game.Workspace.Toy3
}

local function distancecheck()
	local mindistance = 10
	local object
	
	for i, v in pairs(interactable_items) do
		local distance = (v.Position - player.Character.HumanoidRootPart.Position).magnitude 
		if distance < mindistance then
			print("player in range")
			mindistance = distance
			object = v
		else
			print("player not in range")
			v.Keybind.Enabled = false
		end
	end
	return object
end

runservice.RenderStepped:Connect(function()
	local object = distancecheck()
	if object then
		object.Keybind.Enabled = true
	end
end)

So basically the closer part should activate that gui but it activates both and not the closer one
Here is a screenshot:

I’m sure i’m doing something bad, my scripting experiences are not that good :frowning:

The reason they’re both visible is because you’re never setting the object’s Keybind to false, so if the object returns in the RenderStepped once it will forever be active. You should have a variable that stores the previous active part (if there was one). When you get a new part from the distancecheck function, if that part is not the previous part, then disable the previous part.

I can’t test this, but this should work:

local previousObject -- global variable for previous active object (if there was one)

runservice.RenderStepped:Connect(function()
	local object = distancecheck()
	if previousObject and previousObject ~= object then -- disable previous object if a new object is found. Outside of `if object` incase no object is returned. 
		previousObject.Keybind.Enabled = false
	end
	if object then
		object.Keybind.Enabled = true
	end
	previousObject = object -- update previous object. nil if no object is found. 
end)
1 Like

Thank you, it helped me a lot :slight_smile: