How can I maek a E interaction system

So I am trying to make a door system where when E is pressed you go up to the door and swipe your card and then the door opens, I never did this before and really confuses me because how do I like calculate correct distance between the door you want to open (since you need to be close) and which reader to walk to.

If anyone has done this before please tell me because I am really confused about this.

5 Likes

You need to look into loading animations, and using instance.new (to create keycard) and magnitude to create this

1 Like

There have been many posts on this. Check these out:

https://devforum.roblox.com/search?context=topic&context_id=529257&q=E%20to%20interact&skip_context=true

6 Likes
-- Local Script
local player = game:GetService("Players").LocalPlayer
local character
local rootPart

local function onCharacterAdded(newCharacter)
    character = newCharacter
    rootPart = character:WaitForChild("HumanoidRootPart")
end
if player.Character then
    onCharacterAdded(player.Character)
end
player.CharacterAdded:Connect(onCharacterAdded)

local userInputService = game:GetService("UserInputService")
local allDoors = workspace:WaitForChild("Doors") -- Folder of doors that can be opened

local function getDistanceBetween(part1, part2)
    return (part1.Position - part2.Position).Magnitude
end

userInputService.InputBegan:Connect(function(inputObject, gameProcessed)
    if gameProcessed then return end
    for _, door in next, allDoors:GetChildren() do
        if inputObject.KeyCode == Enum.KeyCode.E and getDistanceBetween(rootPart, door) <= 10 then
            print("Open " .. door)
            -- Open door script here, for now I'll do a basic non can collide one
            door.CanCollide = false
            door.Transparency = 0.5
        end
    end
end)

NOTE: with the way I approached this, doors that are opened are CLIENT-SIDED only, if you wanted to make it server-sided, click here to learn about RemoteEvents

2 Likes

So would this go into like starter character scripts?

1 Like

It could go in there yes (or StarterPlayerScripts) and for how I coded it you’d want to make sure all the doors are Parts, not models. If you wanted to edit it you’d have to change some stuff around.

1 Like

And if I’d fire a remote event would I fire the doors name and then it would check if its name is correct to open?

1 Like

How I would go about the remoteEvent would be something like this:

-- Server
local replicatedStorage = game:GetService("ReplicatedStorage")
local doorEvent = replicatedStorage:WaitForChild("DoorEvent")
local doors = {}

for _, door in next, workspace:WaitForChild("Doors"):GetChildren() do
    if doors[door] == nil then
        doors[door] = false -- Opened
    end
end

doorEvent.OnServerEvent:Connect(function(player, door)
    print(player.Name, "fired the event")
    if doors[door] then -- if it's opened, close it
        doors[door] = false
        door.Transparency = 0
        door.CanCollide = true
    else -- else, open it
        doors[door] = true
        door.Transparency = 0.5
        door.CanCollide = false
    end
end)

On the old Local Script I provided, you’d remove the part where it changes the appearance of the door and leave that to the server (you would also have do fire the event to the server)

local Door = workspace.Door -- change this to the path leading to the door model
local UIS = game:GetService("UserInputService")
local Player = game.Players.LocalPlayer
local Open = false
local RequiredCardName = "Card56435" -- What is the name of the card that can open the door? enter it here.
local Display = script.Parent -- also make a text gui(not billboard) and set the text to "E" also another thing make sure the parent of the script is that gui

UIS.InputBegan:Connect(function(Input)
 if Input.UserInputType == Enum.UserInputType.Keyboard then
  if Input.KeyCode == Enum.KeyCode.E then
     if UIS:GetFocusedTextBox() == nil then
        if Player:WaitForChild("Backpack"):FindFirstChild(RequiredCardName) then
          Player:WaitForChild("Backpack")[RequiredCardName].Equipped:Connect(function()
            local Distance = (Player.Character:WaitForChild("UpperTorso").Position-Door.Position).Magnitude
            if Distance <= 10 then
                --Do the code when the door is opened here. I'll just make one :3
                if Open == false then
                  Open = true
                  Door.CanCollide = false
                  Door.Transparency = 1
              else
                  Open = false
                  Door.CanCollide = true
                  Door.Transparency = 0
                 end
               end
       	     end)
   	        end
         end
      end
   end
 end)

workspace.CurrentCamera.Changed:Connect(function()
  local Distance = (Player.Character:WaitForChild("UpperTorso").Position-Door.Position).Magnitude
  if Distance <= 10 then
      Display.Visible = true
      local WSP = workspace.CurrentCamera:WorldToScreenPoint()
      Display.Position = UDim2.new(0,WSP.X,0,WSP.Y)
   else
       Display.Visible = false
  end
end)

Good script but instead of using magnitue you can use https://developer.roblox.com/en-us/api-reference/function/Player/DistanceFromCharacter

1 Like

Didn’t know this function existed, thanks for the input

1 Like

For the game I’m working on, we handle this through object-oriented programming-based classes. The interactive class speaks to our HID (human interface devices) classes which are ultimately linked up to our doors. In other cases, we can configure custom actions to be fired off via BindableEvent when an interaction successfully completes.

Our entire interaction system is under an interactive object class which both the client and server will use. The client uses ContextActionService to determine button presses and releases, the state being configured based on the UserInputState Enum. When an interaction is finished, a remote is fired to the server to start the server’s actions. The server will then perform its validation checks and then accordingly fire off the action event.

While there are many different ways to accomplish this, the general workflow is:
Client sends input -> Server validates request -> Server fires off an action

If you need key-based interaction to work with more than just one thing, it’d best suit you to make an interactive framework so that you can set up certain actions in your game the same way. It would just be a matter of registering an object and then setting an action to be fired when interaction completes.

2 Likes

But how can I like make the player go over to the closest keycard slot I thought of calculating which one is closest to the player

If you’re setting up an interaction system for a door, then you should already have a reference to the HID used for the door. There wouldn’t be a need to find which one is closest to the character because then you might end up making them walk towards a completely unrelated detector.

When you set up interaction on one door (assuming you’re doing this from one script, then it’d be contained in a for loop), you would already have access to at the very least the supermodel of the door. You can then just set up variables that point to different parts of the door. When you get to the interaction bit, you’d simply need to have the character walk up to the HID they activated interaction for.