Enable KeyPress when near object

So,

I want to make when player gets near any object(part, model, npc, etc.) the KeyPress becomes enabled. For example: Player gets near a part and it let’s player to press E. If near KeyPress works if not near then KeyPress is disabled. How can I do it?

2 Likes

You would need to use UserInputService and Magnitude.

First, we need to check if when the player clicked E on their keyboard:

local UIS = game:GetService("UserInputService")
UIS.InputBegan:Connect(function(input, gameProcessed)
    if input.KeyCode == Enum.KeyCode.E then -- Checks if the player clicked E
       if gameProcessed == false then -- Makes sure that the player isn't chatting while clicking E

        end
    end  
end

Next, we need to get the magnitude of how far the player is from a block:

local mag = (game.Players.LocalPlayer.Character.HumanoidRootPart.Position - workspace.Part.Position).magnitude

Then, we check if the player is close enough, and, if it is, we do something:

if mag <= 10 then
      -- Do something
end

I hope this helped, don’t hesitate to ask me anything! (:

3 Likes

So, this part:

if mag <= 10 then
      -- Do something
end

Should be put in here?

if input.KeyCode == Enum.KeyCode.E then -- Checks if the player clicked E
       if gameProcessed == false then -- Makes sure that the player isn't chatting while clicking E
--HERE?
        end
    end

Fixed my code

local Players = game:GetService("Players")
local LocalPlayer = Players.LocalPlayer
local Char = LocalPlayer.Character or LocalPlayer.CharacterAdded:Wait()

local CAS = game:GetService("ContextActionService")

function Pressed(_,__)
    
    if (__ == Enum.UserInputState.End) then
        return
    end

    local Magnitude = (Char:WaitForChild("HumanoidRootPart").CFrame.p - workspace.Part.CFrame.p).Magnitude

    if (Magnitude < 10) then
       print("In distance")
    end
end

CAS:BindAction("description",Pressed,false,Enum.KeyCode.E)
2 Likes

Wow. You guys really don’t have any love for DistanceFromCharacter, do ya?

Just saying - remember that Scripting Support is not a place to ask for code. Asking for tips or pointers is fine, but “how can I do it?” comes off as asking for code (at least from how I’m perceiving it).

Anyway - UserInputService or ContextActionService are your go-tos for handling input. It doesn’t matter which one you use necessarily, but the point is that your input should only be going off as in when you are near said object. If you need multiple objects, be sure to have your interaction objects in a table of some kind so that it’ll be easier for you to work with (and more efficient).

Personally, I prefer the UserInputService because Begin, Ended and Changed input states have explicit methods you can connect to, whereas you need to write to that manually via ContextActionService. I’m too lazy for that. :stuck_out_tongue:

local Players = game:GetService("Players")
local UserInputService = game:GetService("UserInputService")

local LocalPlayer = Players.LocalPlayer

local MAX_DISTANCE = 15

UserInputService.InputBegan:Connect(InputObject, GameProcessedEvent)
    if not GameProcessedEvent then -- Input wasn't handled internally
        if InputObject.KeyCode == Enum.KeyCode.E then
            -- Check distance. Sample check below.
            local DistanceToObject = LocalPlayer:DistanceFromCharacter(Object.Position)
            -- Need to check if it's above 0, since 0 gets returned if there's no root
            if DistanceToObject > 0 and DistanceToObject < MAX_DISTANCE then
                dosomething()
            end
        end
    end
end)

I find that DistanceFromCharacter is a much more elegant solution than magnitude. You pass the check to the engine. The performance difference is fairly negligible, but you have a method available for you so you should make use of it.

DistanceFromCharacter handles everything, from checking the existence of parts to performing distance checks, all for you.Character assemblies are also bound for change, so you wouldn’t need to modify much, if anything, via this method.

7 Likes

real quick fix to this, the conditional with DistanceToObject is reversed, it should be like this:

if DistanceToObject > 0 and DistanceToObject < MAX_DISTANCE then
	dosomething()
end

Other ways to write it:

if DistanceToObject ~= 0 and DistanceToObject < MAX_DISTANCE then
if DistanceToObject == math.clamp(DistanceToObject,1e-300,MAX_DISTANCE) then

Also, I agree that Player:DistanceToCharacter is an amazing method and simplifies many scripts.

1 Like

To this day, I somehow still confuse the < and > operators like a young kid would their rights and lefts. Thanks for the point out! Fixed in the response.

Let me add one more there.

if not (DistanceToObject == 0) and DistanceToObject < MAX_DISTANCE then

I’m not sure if I negated the condition correctly, please let me know if that’s improper.

1 Like

For some reason it says that there is too many end. For example "Expected , got ‘end’ ". Am I missing something? By the way, thanks.

2 Likes