Pressing "E" to interact? Is it simple?

I’ve played many games where I see a prompt to press “E” to interact with something, say an NPC or to sit in a chair. I’m completely lost on how to go about this with my current project. How exactly could I go about creating something to prompt this to players and bring up a UI to talk to NPCs? I’m not a scripter by any means, however I’ve tried to look at free models to kind of rework their work but I can’t seem to find anyone that has successfully created this to make a free model I can use as a reference.

10 Likes

I’ve done something similar to this myself.
What I did was use a BillboardGui, UserInputService and a Magnitude checker.
It’d go like:

  • InputBegan
  • Check if the KeyCode is E and GameProccessedEvent is false
  • Check Magnitude between the player’s Character’s HumanoidRootPart and the part
  • If it passes all the checks, do what you need to.

Helpful links:

8 Likes

EDIT: This still gets quite a bit of attention despite being an older solution. It is now recommended to use ProximityPrompts for new work!

Older solution:
Yes, it really is that simple.

Essentially what you want to do is check the magnitude of the player and if they’re within a certain distance of an interactable object (CollectionService is really good for this!). If so, then you should enable the ‘E prompt’ interface on their screen at the location of the interactable object.

Then you want to use the UserInputService to detect an input from the user, in this case E, check their magnitude again and if they’re in range of the interactable object… do something with that object.

Here’s some example code:

local CS = game:GetService("CollectionService")
local UIS = game:GetService("UserInputService")

UIS.InputBegan:Connect(function(input, gameProcessed)
	if input.UserInputType == Enum.UserInputType.Keyboard then
		if input.KeyCode == Enum.KeyCode.E and not gameProcessed then
			
			for _,Interactable in pairs(CS:GetTagged("Interactable")) do
				if CS:HasTag(Interactable, "Interactable") then
					local Magnitude = (Interactable.Position - game.Players.LocalPlayer.Character.HumanoidRootPart.Position).magnitude
					
					if Magnitude <= 10 then
						-- RUN SOME CODE
					end
				end
			end
		end
	end	
end)

game:GetService("RunService").RenderStepped:Connect(function()
	script.Parent.InteractionPrompt.Visible = false
	
	for _,Interactable in pairs(CS:GetTagged("Interactable")) do
		if CS:HasTag(Interactable, "Interactable") then
			local Magnitude = (Interactable.Position - game.Players.LocalPlayer.Character.HumanoidRootPart.Position).magnitude
			
			if Magnitude <= 10 then
				local coords2D = game.Workspace.CurrentCamera:WorldToScreenPoint(Interactable.Position)
				script.Parent.InteractionPrompt.Position = UDim2.new(0, coords2D.X, 0, coords2D.Y)
				script.Parent.InteractionPrompt.Visible = true
			end
		end
	end
end)

If you want to add a tag to use in the CollectionService, you’d just use :AddTag() on that object.

27 Likes

In addition to CollectionService, this dandy plugin is helpful for adding tags:

7 Likes

Sorry for necropost, But you can enable beta for ProximityPrompts.

5 Likes