Best way to make an "E to Interact" keycard door?

Hi, basically I need help figuring out the most efficient method to do this. I’ve already tried a method that I find uneccessary and I know there is a way I could make it more efficient.

Basically, what it does is constantly checks if there is a door within 10 studs of the player. If so, then if you press “e” it sends a remoteevent to the door to open it. This script may be hard to read so I tried to explain it as best as I could

local player = game.Players.LocalPlayer
local character = player.Character
if not character or not character.Parent then
    character = player.CharacterAdded:wait()
end
local UIS = game:GetService("UserInputService")
local debounce = false

local RegionSize = 10
local function MakeRegion(Pos)
    return Region3.new(Pos - Vector3.new(1,1,1)*(RegionSize/2), Pos + Vector3.new(1,1,1)*(RegionSize/2))
end

while wait(0.1) do
    local Reg = MakeRegion(character.HumanoidRootPart.Position)
    local Parts = workspace:FindPartsInRegion3(Reg,character,math.huge) --ignore parts from the character
    for _,Part in pairs(Parts) do
        if Part.Parent.Name == "DoorL0" or "DoorFrame" then
                
            if (Part.Position - character.HumanoidRootPart.Position).magnitude <= RegionSize/2 then
                local TweenPlaying = Part.Parent.Parent.TweenPlaying
                local RemoteEvent = Part.Parent.Parent.DoorL0Event
                
                UIS.InputBegan:connect(function(input)
                    if input.UserInputType == Enum.UserInputType.Keyboard then
                        if input.KeyCode == Enum.KeyCode.E and Part.Parent.Name == "DoorL0" then

                            if TweenPlaying.Value == false then
                                TweenPlaying.Value = true
                                RemoteEvent:FireServer()
                                wait(6)
                                TweenPlaying.Value = false
                                RemoteEvent = nil
                                Part = nil
                                TweenPlaying = nil
                            end
                        end
                    end
                end)    
            end
        end
    end
end

Thanks for reading

1 Like

instead of a while loop try to use a RunService.RenderStepped function`

will try now, ill edit my comment with results

alright, i should’ve said this from the beginning. RenderStepped is working but the issue is that the script is “remembering” the door, so when I walk further than 10 studs away the remoteevent still fires, even though the values for it should be set to nil.

Enable ProximityPrompt in beta features it’s there and really easy to use

local proximitypromt = --your location here
proximityprompt.triggered:Connect(function()
--Your script

end)

Works with all devices

3 Likes

Small advice: This is not available for LIVE use yet, which means you can only use it in studio.

Why would you recommend him to use RenderStepped every frame? RenderStepped should really be used for camera systems.

Because having a while loop is not a good idea. RenderStepped is only called every frame, so it makes sense if you use RederStepped.

Please don’t make baseless comments like this, it is harmful to new developers. There are definitely good use cases for while loops, and this is one of them. Having this run every frame is unnecessary, especially using RenderStepped (which is fired before the frame is rendered), as the computation running every frame will likely cause performance issues. Also, saying “only every frame” makes no sense as this is the highest frequency you can have.

An extract from the RenderStepped Developer Hub page:

RenderStepped does not run in parallel to Roblox’s rendering tasks and code connected to RenderStepped must be executed prior to the frame being rendered. This can lead to significant performance issues if RenderStepped is used inappropriately. To avoid this, only use RenderStepped for code that works with the camera or character. Otherwise, RunService.Heartbeat should be used.

This interaction doesn’t need real-time response when they are in close proximity, so checking every ~0.1 seconds is sufficient.

Thank you for the response, but having to use a while loop for the E interact is not a good idea (In my opinion). I haven’t used proximity so I don’t know much about. While loop does has its uses, but I would chose RenderStepped