How to make a proximity prompt system like SCP Roleplay?

  1. What do you want to achieve? Keep it simple and clear!
    I want to make a proximity prompt like in SCP Roleplay

  2. What is the issue? Include screenshots / videos if possible!
    The issue is that I have never messed with magnitude (if this is what I need to use).

  3. What solutions have you tried so far? Did you look for solutions on the Developer Hub?
    I tried searching devForum and YouTube

image

There is a possible way to script a ProximityPrompt. Set the style to custom and follow Roblox’s tutorial. For the line part, you can see many topics on the DevForum.

1 Like

Hello, I know that I can set the style to custom. Also, I can’t find any topics about the line part.

Alright, I can help you out here.

You need the position of the 2 parts you want to create a line to:

local part = nil --Replace with the line
function update(p1, p2)
    part.CFrame = CFrame.lookAt(p1, p2)
    local mag = (p1-p2).Magnitude
    part.Size = Vector3.new(0.1, 0.1, mag)
end

This is a simple approach to what you might be looking for.

1 Like

Thanks so much! May I ask when I need to call the update function and when I can use UserInputService?

You should bind it to RenderStepped, for clean and fast movement.

I’m fairly sure SCP Roleplay uses a Beam rather than a part for this interaction prompt (@MetatableIndex can probably shed more light on the internals, since it’s their game :stuck_out_tongue: ).

So, to pull this off you’d create two attachments and set a Beam to connect the two parts when the player is in proximity range. This negates the requirement to use RenderStepped or constantly update a part, because you can just rely on the events provided by ProximityPromptService.

1 Like

I was about to say that, but I wanted to quickly give a simple solution. Setting up attachments for everything is a real waste of time when you can do everything with a Part, and a Part is also in 3D space.

A part-based solution is considerably more complicated to implement - it will require @SilentDevReal to do vector math, and constantly update the part’s position which is intensive and unnecessary.

-- Example
local Players = game:GetService("Players")
local ProximityPromptService = game:GetService("ProximityPromptService")

local LocalPlayer = Players.LocalPlayer
local Character = LocalPlayer.Character or LocalPlayer.CharacterAdded:Wait()

local HumanoidRootPart = Character:WaitForChild("HumanoidRootPart")
local RootRigAttachment = HumanoidRootPart:WaitForChild("RootRigAttachment")

local Beam = Assets:WaitForChild("ProximityBeam"):Clone() -- you'll need to make a Beam and store it somewhere
Beam.Parent = HumanoidRootPart
Beam.Attachment0 = RootRigAttachment

ProximityPromptService.PromptShown:Connect(function(prompt, inputType)
   local promptRoot = prompt.Parent
   local targetAttachment = promptRoot:FindFirstChildWhichIsA("Attachment")
   if not targetAttachment then -- create it (one time only)
      targetAttachment  = Instance.new("Attachment")
      targetAttachment.Parent = promptRoot
   end

   Beam.Attachment1 = targetAttachment
end)

ProximityPromptService.PromptHidden:Connect(function(prompt, inputType)
   local promptRoot = prompt.Parent
   local targetAttachment = promptRoot:FindFirstChildWhichIsA("Attachment")
   if targetAttachment and targetAttachment == Beam.Attachment1 then
      Beam.Attachment1 = nil
   end
end)
4 Likes

Hey, I really appreciate the fact that you made the whole script. Thank you so much! I added the promptHidden event too and it works well.

Hey, I was wondering if you can make a Basic bland one and make it free so I can see? Im learning more about scripting a little and I would appreciate it.

2 Likes