How would I detect if the player is close enough to something to interact with it

Hello everyone.

I want to know how to detect the player if it’s close to a part, and if that player IS close to the part then I want to show a interaction GUI that when you press E it does something.

I don’t know how to make THAT work without the player being close to the part.

I am trying to make a hold E thing for turning on and off a light in my game and I need it to tween a progress bar.

How would I make the hold E thing work too because I have the code in my head. The code in my head that goes into the UserInputService thing is:

local thing = coroutine.create(function()
        while wait() do
        if notHoldingE then
               notHoldingE = false
        else
                notHoldingE = true
                break
end)

coroutine.resume(thing)

tween:Play()
wait(3)
-- Lights on
2 Likes

You can use vector3.magnitude
(30 charss)

2 Likes

I thought that in my head but I don’t know how I would be able to detect how close the player is to the part using that :confused:

if (playersroot.Position-thing.Position).Magnitude < *your dist* then
   --stuff
end
2 Likes

Ok now thats a good start.

How would I detect if the player is holding E?

If they have let go of E then how would I stop the code?

You can use

UserInputService:IsKeyDown(Enum.KeyCode.E)

If you are using a while loop ,the just break the loop once the player is not pressing e or just make an elseif

1 Like

I think that this is a better way to get user input:

UserInputService.InputBegan:Connect(function(key)

Since you want to know when the E key is pressed, check if the key’s KeyCode is equal to E. If it is, show the gui.

1 Like

I have brewed up this code:

local inputServ = game:GetService("UserInputService")
local dist = 5
local isKeyDown = false

local e = coroutine.create(function()
	while wait() do
		if (game.Players.LocalPlayer.Character:WaitForChild("HumanoidRootPart").Position - workspace.Part.Position).Magnitude < dist then
			script.Parent.Parent.Parent.e.Visible = true
		else
			script.Parent.Parent.Parent.e.Visible = false
		end
	end
end)

local r = coroutine.create(function()
	while wait() do
		if (game.Players.LocalPlayer.Character:WaitForChild("HumanoidRootPart").Position - workspace.Part.Position).Magnitude < dist then
			local isKeyDown = inputServ:IsKeyDown(Enum.KeyCode.E)
		else
			local isKeyDown = false
		end
	end
end)

coroutine.resume(e)

coroutine.resume(r)


while wait() do
	if isKeyDown then
		print("HOLDING E")
	end
end

The GUI shows the E thing in the corner BUT… it doesn’t print “HOLDING E” when I am holding E when I am close enough to it.

IsKeydown is a local variable, don’t use that

1 Like

Yep, I found out I put local behind it LOL

It works! Horray! I will update any of you guys when I have issues with the tweening bar bit.

1 Like

Hmm, if I am going to use this part of the code:

while wait() do
	if isKeyDown then
		script.Parent.Parent.Visible = true
		tween:Play()
		wait(2)
		print("Hi")
	else
		tween:Cancel()
		script.Parent.Parent.Visible = false
		script.Parent.Size = UDim2.new(0, 0, 1, 0)
	end
end

How would I make it stop the running the code in the top part of the if?

What do you mean?
(30 charsss)

1 Like

So if the player lets go of E, the tween still plays and it doesn’t stop until it’s done.

But I want it to stop the top part of the if. Which is:

script.Parent.Parent.Visible = true
tween:Play()
wait(2)
print("Hi")

From continuing the tween and doing the function/code after the wait(2)

Try adding a debounce
(30 charssssss)

1 Like

How would I script that then? If I made it break out of the if then it breaks out of the whole while wait() statement.


while wait() do
	if isKeyDown and a variable == true then
		script.Parent.Parent.Visible = true
          the variable = false
		tween:Play()
		wait(2)
		print("Hi")
	elseif not isKeyDown then
		tween:Cancel()
		script.Parent.Parent.Visible = false
		script.Parent.Size = UDim2.new(0, 0, 1, 0)
        The variable =true
	end
end
1 Like

No like I need the actual script because I can’t get my head around this.

Here is the current script I have right now with that in it.

local inputServ = game:GetService("UserInputService")
local tweenServ = game:GetService("TweenService")
local dist = 5
local isKeyDown = false
local tweenInf = TweenInfo.new(2)
local tween = tweenServ:Create(script.Parent, tweenInf, {Size = UDim2.new(1, 0, 1, 0)})

local e = coroutine.create(function()
	while wait() do
		if (game.Players.LocalPlayer.Character:WaitForChild("HumanoidRootPart").Position - workspace.Part.Position).Magnitude < dist then
			script.Parent.Parent.Parent.e.Visible = true
		else
			script.Parent.Parent.Parent.e.Visible = false
		end
	end
end)

local r = coroutine.create(function()
	while wait() do
		if (game.Players.LocalPlayer.Character:WaitForChild("HumanoidRootPart").Position - workspace.Part.Position).Magnitude < dist then
			isKeyDown = inputServ:IsKeyDown(Enum.KeyCode.E)
		else
			isKeyDown = false
		end
	end
end)

coroutine.resume(e)

coroutine.resume(r)


while wait() do
	if isKeyDown then
		script.Parent.Parent.Visible = true
		tween:Play()
		wait(2)
		print("Hi")
	elseif not isKeyDown then
		tween:Cancel()
		script.Parent.Parent.Visible = false
		script.Parent.Size = UDim2.new(0, 0, 1, 0)
	end
end
1 Like

If I press E and let go it still does it.

1 Like