This may seem like a game design at first, but I will basically talk about what I want to do:
If the player is in a specific region (an invisible part), it will open the GUI, if the person leaves said region, the GUI will close. It’s just a simple talk one at the moment, however there seems to be an issue with .Touched and .TouchEnded. When I jump, or rapidly leave and enter the part, the GUI starts not working properly. Not sure where to go about this.
Really, it’s a simple script, here it is:
script.Parent.Touched:Connect(function(h)
local humanoid = h.Parent:FindFirstChild("Humanoid")
if humanoid then
game.ReplicatedStorage.Events.Shop:FireClient(game.Players[h.Parent.Name], "open")
end
end)
script.Parent.TouchEnded:Connect(function(h)
local humanoid = h.Parent:FindFirstChild("Humanoid")
if humanoid then
game.ReplicatedStorage.Events.Shop:FireClient(game.Players[h.Parent.Name], "close")
end
end)
.TouchEnded is unreliable. You should check out some other ways to find out if a player is still in a region, like Region3s and GetTouchingParts(). There have been some topics about these where you will find useful info.
Do you recommend a loop to get whether the player is touching it every so often, or do you think .Touched and then :GetTouchingParts in a function would be better? Or something else? I already have a debounce on the other script that tweens the UI so the amount of “requests” sent isn’t really a concern.
Part.Touched:Connect(function(h)
if h and h.Parent:FindFirstChild("Humanoid") then
-- show gui
repeat wait() until game.Players:GetPlayerFromCharacter(h.Parent):DistanceFromCharacter(part.Position) > 7
-- hide gui
end
end
Obviously not the most optimized but it accomplishes the task that it needs to.
TouchEnded has a stigma of being unreliable, seeing as it occasionally fires even if the player is still on the brick. By substituting TouchEnded for a more “reliable” method in DistanceFromCharacter (or a similar .Magnitude method) eliminates the false firing of TouchEnded while keeping the same functionality - it is the best of both worlds.
I would advise against ever relying on TouchEnded for the reasons listed above - it isn’t worth the time and effort it would take to squash any bugs - at least in this scenario.
Yeah, so I would call GetTouchingParts() on initial touch if that player is the first one within the part, and keep calling it until there are no players in the part anymore. You can do this maybe every .25 seconds
if you wanted to.
Once there are no players in the region, you can break the loop so its not running necessarily, and restart it once a new player touches the part.
Make sure to start this check loop only once until the part is empty again, then break it.
Went with Terry’s solution due to the sheer simplicity, if it does end up causing lag for some reason, I will try using yours next. Thank you for your contribution though, I did some research and I may be able to implement it elsewhere.
There were a few errors, I’ll post the fixed version in case anyone needs this in the future:
script.Parent.Touched:Connect(function(h)
if h and h.Parent:FindFirstChild("Humanoid") then
--show
repeat wait() until game.Players:GetPlayerFromCharacter(h.Parent):DistanceFromCharacter(script.Parent.Position) > 7
--hide
end
end)
That’s basically a magnitude check, which will suffice. It’s when you want to find out if something is in a non circular region that Region3 and GetTouchingParts are useful.
In this scenario, I wouldn’t rely on the Touched and TouchEnded events, but rather Region3. I recommend checking out @ForeverHD’s Zone+ module, as it may serve as a more reliable alternative.