Problem with finding the player character [UNSOLVED]

  1. What do you want to achieve?
    I want to get the player character when a player touches a part

  2. What is the issue?
    When there’s 2+ players in the game it returns nil when any of the player touches the part

  3. What solutions have you tried so far?
    I tried to talk with some people on discord and checked for a way to solve this issue on the dev forum but nothing seemed to work

Would appreciate any help, sorry if this isn’t the right category

checkpoints.Touched:Connect(function(hit)
					if touchingCheckpoint == true then
						return
					end
					touchingCheckpoint = true
					
					local playerChar = players:GetPlayerFromCharacter(hit.Parent)
					local plr = player
					
					print(player.Name.. " Touched the main part")
					
					if playerChar and playerChar == plr then
						-- does something
					else
						print("Player is nil") -- prints this only if there are 2 or more players in the game, if there's only one player it'll not print
						task.wait(smallCooldown)
						touchingCheckpoint = false
						return
					end

I noticed “plr = player” Can you tell me what’s player?

1 Like

shouldnt this be called player considering this would give you the player and not the players character?

Player is the local player idk why I have this value but it’s there, just consider it’s the localplayer

1 Like

Is this even a server script? What is your player variable in this script?

checkpoints.Touched:Connect(function(hit)
    if touchingCheckpoint == true then return end
    touchingCheckpoint = true

    local player = players:GetPlayerFromCharacter(hit.Parent)

    if player ~= nil then
        -- do stuff
        
        touchingCheckpoint = false
    else
        print("no player")
        
        task.wait(smallCooldown)
        touchingCheckpoint = false
    end
end)

it works but now I need to check if the player character is actually equal to the player name or else it’ll just do the function for every players

So is this a LocalScript then?

local Players = game:GetService("Players")
local touchingCheckpoint = false

checkpoints.Touched:Connect(function(hit)
    if touchingCheckpoint == true then return end
    touchingCheckpoint = true

    local player = Players:GetPlayerFromCharacter(hit.Parent)

    if player == Players.LocalPlayer then
        -- do stuff
        
        touchingCheckpoint = false
    else
        task.wait(smallCooldown)
        touchingCheckpoint = false
    end
end)
1 Like

Hello, sorry for the late answer I wasn’t home for a few days.

“if playerChar ~= nil and playerChar == player then” works fine to know if it’s actually the player that touches the part that is touching the part.

The only problem is that im making a system that whenever a player touches a part, the part goes inside a table “Table[1]” and the next time the player “dies” he’s teleported back to Table[1].CFrame (kinda like a checkpoint).

The unnormal issue is that it works perfectly fine for player 1, but for player 2, 3 until infinite, it only works if the player leaves the part (which is an issue since the part is huge).

– Important
Do you have any idea on how to make that if a player actually touches a part then we can do whatever. Since now, it only works for one player and every other players are required to leave the specific part the get the table[1].

Everything is managed by a local script

checkpoints.Touched:Connect(function(hit) -- touches event
					if touchingCheckpoint == true then
						return
					end
					touchingCheckpoint = true -- debounce

					local playerChar = players:GetPlayerFromCharacter(hit.Parent) -- getting the player character

					if playerChar ~= nil and playerChar == player then -- checking if the player is actually the player
						print(player.Name) -- prints only if player 2 left the main part, prints regardless on player 1
						
						local checkpointTouched = checkpoints -- checks what part the player touched
						
						if #currentCheckpoint == 0 then -- if the table is empty then
							table.insert(currentCheckpoint, checkpointTouched) -- insert the part inside the table
							print(currentCheckpoint) -- prints only if player 2 left the main part, prints regardless on player 1
						end

						if #currentCheckpoint == 1 then -- if the table has 1 value (Not important works perfectly fine)
							if currentCheckpoint[1] == checkpointTouched then -- if the first value of the table = the checkpoint then
								print("The player already Touched this main part")
							else
								table.remove(currentCheckpoint, 1) -- else it removes the first value
								table.insert(currentCheckpoint, checkpointTouched) -- then it adds the new value
							end
						end

						task.wait(TASK_WAIT_ONE_SECOND)

						touchingCheckpoint = false -- debounce
					else
						print("no player") -- prints for everyplayer no matter what
						
						task.wait(smallCooldown)
						touchingCheckpoint = false
						return
					end
				end)
1 Like

Here’s what AI said: “The issue with your code is that the touchingCheckpoint variable is shared among all players. This means that when one player touches the checkpoint, it sets touchingCheckpoint to true, which affects all other players as well. To fix this, you need to create a debounce for each individual player.”

And AI’s rewritten code (edit as needed, and probably remove touchingCheckpoint):

-- Table to store the checkpoint for each player
local playerCheckpoints = {}

checkpoints.Touched:Connect(function(hit) -- touches event
	local playerChar = players:GetPlayerFromCharacter(hit.Parent) -- getting the player character
	
	if playerChar then -- checking if the player is actually the player
		local player = players:GetPlayerFromCharacter(playerChar) -- get player object from character
		if not player then return end -- if no player object found, return

		if not playerCheckpoints[player] then
			playerCheckpoints[player] = { currentCheckpoint = {}, touchingCheckpoint = false }
		end

		local playerData = playerCheckpoints[player]

		if playerData.touchingCheckpoint == true then
			return
		end
		playerData.touchingCheckpoint = true -- debounce

		print(player.Name) -- prints only if player 2 left the main part, prints regardless on player 1
		
		local checkpointTouched = checkpoints -- checks what part the player touched
		
		if #playerData.currentCheckpoint == 0 then -- if the table is empty then
			table.insert(playerData.currentCheckpoint, checkpointTouched) -- insert the part inside the table
			print(playerData.currentCheckpoint) -- prints only if player 2 left the main part, prints regardless on player 1
		end

		if #playerData.currentCheckpoint == 1 then -- if the table has 1 value (Not important works perfectly fine)
			if playerData.currentCheckpoint[1] == checkpointTouched then -- if the first value of the table = the checkpoint then
				print("The player already Touched this main part")
			else
				table.remove(playerData.currentCheckpoint, 1) -- else it removes the first value
				table.insert(playerData.currentCheckpoint, checkpointTouched) -- then it adds the new value
			end
		end

		task.wait(TASK_WAIT_ONE_SECOND)

		playerData.touchingCheckpoint = false -- debounce
	else
		print("no player") -- prints for every player no matter what
		
		task.wait(smallCooldown)
		return
	end
end)

Edit: Here’s what changed

  1. A table playerCheckpoints is created to store individual player data.
  2. For each player, a separate debounce (touchingCheckpoint) and currentCheckpoint table are maintained.
  3. The debounce check and updates are now player-specific, avoiding conflicts between different players.

Do you really think it was the issue? I’ve made a table outside of this function, and managed to fix this bug only by making the player spawns a bit higher than the part (making every player spawning touching the part).

If your issue is real I’ll change my code but could you please tell me how is it possible for “a variable to be shared with every player” in a local script?

ngl i’m doubting your chat gpt a bit lol

yeah tbh that confused me, but u shld at least try it, and u don’t have to remove your script, just make a new one and disable the other one, or make ur code a comment and just copy and paste. It solves a lot of scripting issues for me so at least try it.

And tbh I’m not so sure what specifically you’re trying to achieve with the checkpoint.

How I would go about making one is instancing a global variable under each player and a global variable under the checkpoints, (or attribute), and when they touch a checkpoint (detected using a normal/server script), change the player’s global variable to match the one in the checkpoint. Then when the player needs to respawn just loop through the checkpoints (probably in a folder) w/ a for loop, that checks to see if the global variable is matching the player’s variable. Then when the player respawns u can change the CFrame of the player’s character w/ MoveTo (although u gotta use a wait before moveto)