How would I fix this client issue?

Hi - I’m currently making a death system like Phasmophobia, where if you die, you become a spectator-ghost and the players who are alive can’t see you.

Issue: I’m having problems making this system multi-supported. What I mean with that is that if 2 players are dead, THEY can see each other & the person who’s still alive CANNOT see them.

Here is a picture of when it ‘kinda’ works:


Left player is alive, and can’t see the dead Right Player.

When both players are dead, this happens:

Neither player can see each other, but they’re both dead.
Who can help me?

SERVER:

local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local MarketplaceService = game:GetService("MarketplaceService")

local ReviveID = 1363606471

local DeadPlayers = {}

Players.PlayerAdded:Connect(function(Player)
	local Dead = Instance.new("BoolValue")
	Dead.Value = false
	Dead.Name = "Dead"
	Dead.Parent = Player
	
	Player.CharacterAdded:Connect(function(Character)
		if Player.Dead.Value == true then
			repeat task.wait() until Character:WaitForChild("HumanoidRootPart", 60)
			for i, v in pairs(Character:GetChildren()) do
				if v:IsA("MeshPart") then
					v.Transparency = 1
				end
				if v:IsA("Accessory") then
					v.Handle.Transparency = 1
				end
			end
			Character.Head["face"]:Destroy()
			ReplicatedStorage.DeathEvent:FireAllClients("HidePlayer", DeadPlayers)
		end
		Character.Humanoid.Died:Connect(function()
			Player.Dead.Value = true
			table.insert(DeadPlayers, Player)
		end)
	end)
end)

MarketplaceService.ProcessReceipt = function(receiptInfo)
	if receiptInfo.ProductId == ReviveID then
		local Player = Players:GetPlayerByUserId(receiptInfo.PlayerId)
		Player.Dead.Value = false
		ReplicatedStorage.DeathEvent:FireClient(Player, "HideButton")
		Player:LoadCharacter()
		return Enum.ProductPurchaseDecision.PurchaseGranted
	end
end

CLIENT (STARTERCHARACTERSCRIPTS):

local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")

local Player = Players.LocalPlayer
local Character = script.Parent

local UpdatedTable

ReplicatedStorage.DeathEvent.OnClientEvent:Connect(function(Argument, Table)
	if Argument == "HidePlayer" then
		UpdatedTable = Table
		--[[for i, v in pairs(Character:GetChildren()) do
			if v:IsA("MeshPart") then
				v.Transparency = 0.5
			end
			if v:IsA("Accessory") then
				v.Handle.Transparency = 0.5
			end
		end]]
		Player.PlayerGui.ReviveUI.Revive.Visible = true
	elseif Argument == "HideButton" then
		Player.PlayerGui.ReviveUI.Revive.Visible = false
	end
end)

while true do
	if UpdatedTable ~= nil then
		warn("table found")
		for i, v in pairs(UpdatedTable) do
			if Player.Name == v.Name then
				if v.Dead.Value then
					for a, b in pairs(v.Character:GetChildren()) do
						if b:IsA("MeshPart") then
							b.Transparency = 0.5
						end
						if b:IsA("Accessory") then
							b.Handle.Transparency = 0.5
						end
						print("DONE")
					end
				end
			end
		end
	end
	task.wait(.1)
end

Thank you!!

2 Likes

You have a server table, containing all players that are dead. Sending that table to all clients, to make those players in table transparent.

So, dead players are always invisible client side to all players, including the players that are dead too.

You could add an statement, if I am dead, do not make dead players table transparent.

Could be, if Im in the same table as dead players, do not perform the transparent change function.

So, before to run the transparency change, check if the current player is in the table.
if not table.find(deadPlayers, me) then

1 Like

Sorry to say - I think I’m taking your post too literally.

Am I implementing this incorrectly?

while true do
	if UpdatedTable ~= nil then
		warn("table found")
		for i, v in pairs(UpdatedTable) do
			if Player.Name == v.Name then
				if v.Dead.Value then
					if not table.find(UpdatedTable, Player) then
					for a, b in pairs(v.Character:GetChildren()) do
						if b:IsA("MeshPart") then
							b.Transparency = 0.5
						end
						if b:IsA("Accessory") then
							b.Handle.Transparency = 0.5
						end
						print("DONE")
					end
					end
				end
			end
		end
	end
	task.wait(.1)
end

I suppose Player in that local script, reference the game.Players.LocalPlayer

Then

while true do
	if UpdatedTable ~= nil then
		warn("table found")
		for i, v in pairs(UpdatedTable) do
			if Player ~= v then -- no need to check the name, just the player instance, and instead of equal ==, should be different ~=
				if v.Dead.Value then -- Is this needed? this is a table made with all players that are dead, is it needed to check the player dead value again?
					if not table.find(UpdatedTable, Player) then -- this should work, if the table contains player instances, not string names
						for a, b in pairs(v.Character:GetChildren()) do
							if b:IsA("MeshPart") then
								b.Transparency = 0.5
							end
							if b:IsA("Accessory") then
								b.Handle.Transparency = 0.5
							end
							print("DONE")
						end
					end
				end
			end
		end
	end
	task.wait(.1)
end

EDIT, sorry, let me check again this, Im a little distracted :v

1 Like

Small changes to that script:

I suppose, if I am alive, dead players should be fully transparent
And if I am dead, dead players should be semiTransparent

while true do
	if UpdatedTable ~= nil then
		warn("table found")
		for i, v in pairs(UpdatedTable) do
			if Player ~= v then -- no need to check the name, just the player instance
				if v.Dead.Value then -- Is this needed? this is a table made with all players that are dead, is it needed to check the player dead value again?
					if not table.find(UpdatedTable, Player) then -- If Im not dead, make dead players fullyTransparent
						for a, b in pairs(v.Character:GetChildren()) do
							if b:IsA("MeshPart") then
								b.Transparency = 1
							end
							if b:IsA("Accessory") then
								b.Handle.Transparency = 1
							end
							print("DONE")
						end
					else -- If I am dead same as other dead players, make them semiTransparent
						for a, b in pairs(v.Character:GetChildren()) do
							if b:IsA("MeshPart") then
								b.Transparency = 0.5
							end
							if b:IsA("Accessory") then
								b.Handle.Transparency = 0.5
							end
							print("DONE")
						end
					end
				end
			end
		end
	end
	task.wait(.1)
end

To make things clearer:

local function HandlingTransparency(targetPlayer, Transparency)
	for a, b in pairs(targetPlayer:GetChildren()) do
		if b:IsA("MeshPart") then
			b.Transparency = Transparency
		end
		if b:IsA("Accessory") then
			b.Handle.Transparency = Transparency
		end
		print("DONE")
	end
end

while true do
	if UpdatedTable ~= nil then
		warn("table found")
		for i, v in pairs(UpdatedTable) do
			if Player ~= v then
				if not table.find(UpdatedTable, Player) then
					HandlingTransparency(v.Character, 1) -- If Im not dead, make dead players fullyTransparent
				else
					HandlingTransparency(v.Character, 0.5) -- If I am dead same as other dead players, make them semiTransparent
				end
			else
				HandlingTransparency(v.Character, 0.5) -- I am dead, turn me semitransparent for myself
			end
		end
	end
	task.wait(.1)
end
1 Like

Thank you so so much for fixing the code! It works like a charm now! :smiley:

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.