Roblox proximity prompt script (hold E to interact)
The “E Pick up” bubble you see in most Roblox games. One server script gives the player an item; the variations change the key, range and look.
ScriptUpdated November 2, 2026
Where to put it
Script — Inside the part (Workspace > Pickup > Script). It runs on the server, so players can't change what it does.
- Insert an anchored Part where the item should be, then insert a
ProximityPromptand a Script inside it. - Put the Tool players should get (for example a tool named
Sword) in ServerStorage, so it can't be grabbed directly.
The script
local ServerStorage = game:GetService("ServerStorage")
local part = script.Parent
local prompt = part:WaitForChild("ProximityPrompt")
local tool = ServerStorage:WaitForChild("Sword")
prompt.ActionText = "Pick up"
prompt.ObjectText = tool.Name
prompt.HoldDuration = 0.5 -- seconds to hold E; 0 = instant
prompt.MaxActivationDistance = 10
prompt.Triggered:Connect(function(player)
local backpack = player:FindFirstChildOfClass("Backpack")
if not backpack then
return
end
local character = player.Character
-- One copy per player: skip if it's in the backpack or in their hand.
if backpack:FindFirstChild(tool.Name) or (character and character:FindFirstChild(tool.Name)) then
return
end
tool:Clone().Parent = backpack
end)How it works
- The prompt appears when a player is within
MaxActivationDistancestuds. On a keyboard it shows E, on a gamepad a button, and on phones a tap button. HoldDurationturns a tap into a hold with a progress ring — good for actions that shouldn't happen by accident.Triggeredfires on the server with the player who used it, so the server decides what they get. Clients can't give themselves items.
Variations
Cooldown per player
Lets each player use the prompt once every 30 seconds — useful for a free reward or a food stand.
local COOLDOWN = 30
local lastUsed = {}
prompt.Triggered:Connect(function(player)
local now = os.clock()
if lastUsed[player] and now - lastUsed[player] < COOLDOWN then
return
end
lastUsed[player] = now
-- give the reward here
end)
game:GetService("Players").PlayerRemoving:Connect(function(player)
lastUsed[player] = nil
end)Different key, range and visibility
Set these in Properties or in the script. RequiresLineOfSight hides the prompt when a wall is between the player and the part.
prompt.KeyboardKeyCode = Enum.KeyCode.F
prompt.GamepadKeyCode = Enum.KeyCode.ButtonY
prompt.MaxActivationDistance = 6
prompt.RequiresLineOfSight = false
prompt.Exclusivity = Enum.ProximityPromptExclusivity.OnePerButtonYour own prompt look
Set the prompt's Style to Custom and draw it yourself in a LocalScript in StarterPlayerScripts. The server script above stays the same.
local ProximityPromptService = game:GetService("ProximityPromptService")
ProximityPromptService.PromptShown:Connect(function(prompt)
if prompt.Style ~= Enum.ProximityPromptStyle.Custom then
return
end
local gui = Instance.new("BillboardGui")
gui.Size = UDim2.fromOffset(160, 40)
gui.StudsOffset = Vector3.new(0, 3, 0)
gui.AlwaysOnTop = true
gui.Adornee = prompt.Parent
local label = Instance.new("TextLabel")
label.Size = UDim2.fromScale(1, 1)
label.BackgroundColor3 = Color3.fromRGB(20, 20, 30)
label.TextColor3 = Color3.new(1, 1, 1)
label.Font = Enum.Font.GothamBold
label.TextScaled = true
label.Text = "[" .. prompt.KeyboardKeyCode.Name .. "] " .. prompt.ActionText
label.Parent = gui
Instance.new("UICorner", label)
gui.Parent = game:GetService("Players").LocalPlayer.PlayerGui
prompt.PromptHidden:Wait()
gui:Destroy()
end)Common mistakes
- Handling
Triggeredin a LocalScript to give items: the item exists only on that player's screen and exploiters can fire it at will. Give items on the server. - Putting the prompt somewhere it can't show: it needs a Part or an Attachment as its parent (a Model works only with a PrimaryPart).
- The prompt never appears because the part is inside a wall or another part — move it, or turn off
RequiresLineOfSight. - Many prompts close together all show at once. Lower
MaxActivationDistanceor setExclusivitytoOnePerButton.
FAQ
How do I make a proximity prompt in Roblox Studio?
Select a part, click + and insert a ProximityPrompt, then add a Script that listens to prompt.Triggered. The player who pressed it is passed to the function.
How do I change the proximity prompt key?
Set KeyboardKeyCode (for example Enum.KeyCode.F) and GamepadKeyCode. Phones always get a tap button.
Should a proximity prompt script be a Script or a LocalScript?
A Script, so the server decides what happens. Use a LocalScript only for looks, such as a custom prompt design.
Why is my proximity prompt not showing?
Check that Enabled is on, the player is within MaxActivationDistance, nothing blocks the line of sight, and the prompt sits in a Part or Attachment.