Go near NPC to open shop

I’m still continuing the meme game and I’m trying to make it so if the player goes near the shop NPC, a shop GUI opens and the player can shop. I tried searching and it only gives me “Click button on side of the screen to open Shop,” which is not what I want. I really need the help I don’t want to spend another half hour.

1 Like

You can use a Region3 to detect if the player is in a set region around the NPC, or you could make a part and get a touched event from that part.

Region3 documentation if you need it:

You want to use Region3 to detect when the player is within a certain area. Region3 can be difficult for some so here’s something I created a bit of ago.

I placed this as a LocalScript inside one of my GUI’s so it can stay local to the player and that way I know which GUI this will be affecting.

--regionArea is the BasePart I am referencing which is covering the area.
local regionArea = workspace.Shop_Area
local positionA = regionArea.Position - (regionArea.Size / 2)
local positionB = regionArea.Position + (regionArea.Size / 2)
local region = Region3.new(positionA,positionB)

--Debounce table so that way it does not count a player multiple times in a single second.
local playerDebounce = {}
local player = game.Players.LocalPlayer

while true do wait()
	local partsInRegion = workspace:FindPartsInRegion3(region, nil, math.huge)
	local isInRegion = false
    --Loops through anything that is set foot in the area. If the player is detected, then it makes the variable isInRegion = true
	for i, v in pairs(partsInRegion) do
		if game.Players:GetPlayerFromCharacter(v.Parent) == game.Players.LocalPlayer then
			isInRegion = true
		end
	end

	if isInRegion == true then
		if not playerDebounce[player.UserId] then
			--Do stuff if player enters
            playerDebounce[player.UserId] = player
		end
	else
		if playerDebounce[player.UserId] then
			--Do stuff if player leaves
			playerDebounce = {}
		end
	end
end

Here’s how mine turned out, I think it rocks!

4 Likes

I can’t figure this out so I’ve decide to try something else. Thank you for the answers though.

Will running an infinite loop with such a short wait like that decrease performance on low-end devices? im always afraid to make too many loops, especially ones that run so quickly.

nah RunService and a custom Yield function would do

This is currently one of the most feasible solutions for Region3. I don’t personally don’t think creating a loop is going to be the end of the world.

I’d love to hear another alternative that’s not a loop but still provides assurance of where the player is. Because I’m still learning this stuff too!

If Region3 is a bit hard for you to use, you could instead use BasePart.Touched and BasePart.TouchEnded e.g:
Screen Shot 2021-01-20 at 9.33.49 AM
Using the yellow part as our DetectionPart we can just write the following code:

local PLRS = game:GetService("Players")
local function getPlr(prt) -- checks if the part that touched the block is from a player's character
    return PLRS:GetPlayerFromCharacter(prt.Parent)
end
DetectionPart.Touched:Connect(function(hitPart)
    local plr = getPlr(hitPart)
    if (plr) then
       -- open gui
    end
end)
DetectionPart.TouchEnded:Connect(function(hitPart)
    local plr = getPlr(hitPart) 
    if (plr) then
       -- close gui
    end
end)