Display Player Name on Part.OnTouched

I want to make it so , that when you touch a part , it automatically records your name and concatenates it with a phrase and then that text is displayed on a TextLabel at game.Starter.ScreenGui.complete and that TextLabel is set to visible=true so players see it , then after 3 seconds it closes, but i’m not getting anywhere with this script :
ServerScript in Part

local Players = game:GetService("Players")

script.Parent.Touched:connect(function(touched)

local p = #Players

local h =  p:FindFirstChild("Humanoid")

for p,x in pairs(touched) do
	 
	if h then 

      if h~=nil then
       
  local playername = p.Name

--[[              local gg =   p:FindFirstChild("PlayerGui")
         gg.ScreenGui.? ]]

      local gg = game.StarterGui.ScreenGui.complete
   
           gg.Visible =true
  
       gg.Text = p.Name .. "Has Climbed The stairs"

   wait(3.3) gg.Visible = false

 end 
	end
end

	end)

image

Edit : sorry about the indentation
–ignore the script INVISER , it does nothing

also excuse me if I did something COMPLETELY wrong.

1 Like

You spelt Humanoid wrong in the h variable, and what is the purpose of the pairs loop?

The indentation in this script makes it very hard to read.

I dont know why I looped , I just dont know what to do !
I’ve tried so many methods I just couldn’t get it to work.

You can use Players service’s :GetPlayerFromCharacter to get a player from hit.Parent (obviously if there is).
Then loop through Players service’s :GetPlayers and update every player’s UI:

local players = game:GetService("Players")

script.Parent.Touched:Connect(function(hit)
    local touchedPlayer = players:GetPlayerFromCharacter(hit.Parent)
    if touchedPlayer then
        for _, loopedPlayer in pairs(players:GetPlayers()) do
            if loopedPlayer:FindFirstChild("PlayerGui") then --Just to check!
                coroutine.wrap(function() --coroutine wrap to ensure the wait() doesn't yield the entire for loop!
                    local Complete = loopedPlayer.PlayerGui.ScreenGui.complete
                    Complete.Visible = true
                    Complete.Text = touchedPlayer.Name .. " has climbed the stairs!"
                    wait(3.3)
                    Complete.Visible = false
                end)()
            end
        end
    end
end)

Remember that StarterGui’s contents are only replicated to players on join.
Also, keep in mind about indentation and easy to remember variables names - this is important when debugging.

3 Likes

But for _, looped player in pairs (players:GetPlayers()) do
why do we wrap it in courotine

1 Like

I named the index underscore because we’re not using the index, the player from the array is named loopedPlayer.

You need to coroutine wrap the inside because of the wait(), this would yield the thread and therefore the next player in the array would see the gui after the yield.
Coroutine wrapping it creates a psuedo-thread which then the wait() yields in that psuedo-thread and not the current.

1 Like

GetPlayers returns an array. Use ipairs for looping through arrays.

I don’t feel like typing the why so here’s a link to other posts where I do explain the why:
https://devforum.roblox.com/search?q=ipairs%20%40colbert2677%20%23help-and-feedback%3Ascripting-support