I am currently working on a city game and in this there is a gun store. I’ve been trying to make it so that a GUI will appear on a player’s screen when they enter the shop through the door. However I have no idea how to do this, I’ve tried to find proximity related articles on the Wiki but can’t.
Basically a ontouch script, when the player enters, they step on soemthing, and a GUI pops up?
game.Players.PlayerAdded:Connect(function(plr)
script.Parent.Touched:connect(function(hit)
if hit.Parent:FindFirstChild(“Humanoid”) then
plr.PlayerGui.ScreenGui.Frame.Visible = true
end
end)
end)
Okay thanks I’ll give that a go.
You can use this:
game.Players.PlayerAdded:Connect(function(plr)
script.Parent.Touched:connect(function(hit)
if hit.Parent:FindFirstChild(“Humanoid”) then
plr.PlayerGui.ScreenGui.Frame.Visible = true
end
end)
end)
Not 100% it works, I’m on mobile and I found one of my old scripts, and this was one.
A good way of doing it is putting a brick infront of the counter that will act like a hitbox. When a player approaches the counter (if they don’t already have a gui) it will give them the gui. To remove the gui just do a brick around the exits of the building that a player will touch. (Along with an exit button on the gui itself ofcourse.)
@kinkocat @scytheslayin
Thank you both for the help, I incorporated both ideas by making two on touch functions, one for the counter which makes the GUI visible and one for the door which (if the player hasn’t already closed it) makes it not visible.
https://gyazo.com/9341ce07257dcf18f1be73e4e2801395
very happy now
What you’re trying to accomplish isn’t a proximity-based item, it’s more like an event trigger. The solution posted is a reinventing of the wheel where unnecessary and you should never handle Guis from the server. It’s also bad practice to do so and on top of that, I can sense several code smells.
What you should do instead is have a LocalScript within PlayerScripts (in Roblox Studio, you would place this inside StarterPlayerScripts) and handle the event from there. Use this code (oh my, I absolutely hate the fact that I’m spoonfeeding code right now):
local Players = game:GetService("Players")
local LocalPlayer = Players.LocalPlayer
local PlayerGui = LocalPlayer:WaitForChild("PlayerGui") -- Not implicitly available
local Gui = PlayerGui:WaitForChild("ScreenGui") -- Use better names, please
local Trigger = workspace:WaitForChild("StorePrompt") -- Or whatever your brick's name is
local Debounce = false -- Don't want your game lagging here when Touched fires often per frame
Trigger.Touched:Connect(function (hit)
if not Debounce then
Debounce = true
if hit and hit:IsDescendantOf(LocalPlayer.Character) then -- We don't index Character as a variable since this script won't refresh
Gui.Frame.Visible = true
end
delay(1, function()
Debounce = false
end)
end
end)
This code is better than the current marked solution in the following ways:
- Touched function is debounced. Considering the Touched function is called several times per frame, you don’t want this function running so often.
- You should handle as much as you can from the client where possible. This whole item can be ran on the client, there’s no need for the server to get involved.
- There is literally no point in using PlayerAdded. It’s unnecessary. Remove it and you’ll see that the code works all the same. This code is just going to connect Touched events every time someone joins and that’s going to get real bad once you have more players in.
- Server memory and resources are saved so they can be better put to other tasks.
“OnTouch”
Honestly you’re right I was just looking for a solution that worked opposed to one that was the best. I’ll implement this tomorrow thank you!
I hate to necro bump but a better practice would be to connect the OnTouch event to a RemoteEvent that then fires to the local script to make both sides more secure. Again, sorry.
That’s actually not better, you don’t need a remote here. Involving a remote would incur unnecessary network overhead that can be completely rid of by making this system completely client-side.
The server realistically doesn’t need to do anything because this interaction is all client-sided (checking proximity to a location before showing a Gui). Security isn’t required because you aren’t performing critical game actions that need to replicate, only the client is going to receive this.
When thinking about how to approach a system, you want to take into account what exactly is going to be done here and from there, what events actually need to be involved. Reducing server-side strain by pushing tasks to the client will help you in the long run for performance and memory conservation. Something that’s only relevant to the current client can likewise also be handled completely by them.
I see, thanks for clarifying why a remote event wouldn’t be an optimal solution.
But in cases such as the ones you find in Jailbreak where you must be in close proximity to a moving player, wouldn’t a script and remote event make much more sense so an exploiter can’t hold e on a player from 200 meters away?
That’s a different scenario altogether. You have a keybind interaction system that has some kind of action that will replicate, it’s not just a simple touch-and-show system. In that case, you would be doing proximity checks on both the client and the server: from the client for UX and immediate response’s sake, and from the server for validation’s sake. The server isn’t needed if it’s still just purely a client-sided action because exploiters can bypass that check by directly bypassing conditions.