How do I add multiple players to my lobby?

Hello there, I was trying to fix my lobby that looks like the one from Fortnite. I wanna achieve multiple players being shown. I use a viewport frame for this. The error is that the other player’s parent is nil. If anyone can then please help.

Local Script:

game.StarterGui:SetCoreGuiEnabled(Enum.CoreGuiType.Backpack, false)
game.StarterGui:SetCoreGuiEnabled(Enum.CoreGuiType.Health, false)
game.StarterGui:SetCoreGuiEnabled(Enum.CoreGuiType.PlayerList, false)
game.StarterGui:SetCoreGuiEnabled(Enum.CoreGuiType.EmotesMenu, false)
game.StarterGui:SetCoreGuiEnabled(Enum.CoreGuiType.Captures, false)

task.wait(1)

local plrs = game.Players
local plr = plrs.LocalPlayer

local usedleftside = false
local leftplayer
local usedrightside = false
local rightplayer

local e = plr.Character or plr.CharacterAdded:Wait()

game["Run Service"].RenderStepped:Connect(function()
	plr.PlayerGui.Main.ViewportFrame.Models:ClearAllChildren()
	for i, v in workspace:GetChildren() do
		if v:FindFirstChild("Humanoid") and game.Players:GetPlayerFromCharacter(v) then
			v.Archivable = true
			if #game.Players:GetPlayers() == 1 then
				if v == e then
					local player = v:Clone()
					player.Name = e.Name.."Rig"
					player.Parent = plr.PlayerGui.Main.ViewportFrame.Models
					player:PivotTo(plr.PlayerGui.Main.ViewportFrame.Lobby.Pads.MiddlePad.Location.CFrame)
					local nameClone = plr.PlayerGui.Main.Middle -- the name clones are the overhead guis
					
					nameClone.name.Text = plr.DisplayName

					local ready = plr:WaitForChild("plrReady")

					if e.Name == "LittleDevYT2" then
						nameClone.dev.Visible = true
					end

					ready:GetPropertyChangedSignal("Value"):Connect(function()
						if ready.Value then
							nameClone.ready.Text = "Ready"
							nameClone.ready.TextColor3 = Color3.fromRGB(0, 255, 0)
							nameClone.ready.UIStroke.Color = Color3.fromRGB(73, 255, 79)
							task.wait(1)
							if workspace.plrsReady.Value == #game.Players:GetPlayers() then
								nameClone.ready.Text = "Joining"
								nameClone.ready.TextColor3 = Color3.fromRGB(255, 255, 255)
								nameClone.ready.UIStroke.Color = Color3.fromRGB(147, 147, 147)
								task.wait(3)
								if nameClone.ready.Text ~= "Not Ready" then
									nameClone.ready.Text = "Failed to join"
									nameClone.ready.TextColor3 = Color3.fromRGB(255, 0, 0)
									nameClone.ready.UIStroke.Color = Color3.fromRGB(255, 90, 90)
								end
							end
						else
							nameClone.ready.Text = "Not Ready"
							nameClone.ready.TextColor3 = Color3.fromRGB(255, 0, 0)
							nameClone.ready.UIStroke.Color = Color3.fromRGB(255, 90, 90)
						end
					end)


					workspace.plrsReady:GetPropertyChangedSignal("Value"):Connect(function()
						task.wait(1)
						if workspace.plrsReady.Value == #game.Players:GetPlayers() then
							nameClone.ready.Text = "Joining"
							nameClone.ready.TextColor3 = Color3.fromRGB(255, 255, 255)
							nameClone.ready.UIStroke.Color = Color3.fromRGB(147, 147, 147)
							task.wait(3)
							if nameClone.ready.Text ~= "Not Ready" then
								nameClone.ready.Text = "Failed to join"
								nameClone.ready.TextColor3 = Color3.fromRGB(255, 0, 0)
								nameClone.ready.UIStroke.Color = Color3.fromRGB(255, 90, 90)
							end
						end
					end)
				end
			elseif #game.Players:GetPlayers() == 2 then
				if v == e then
					local player = v:Clone()
					player.Name = e.Name.."Rig"
					player.Parent = plr.PlayerGui.Main.ViewportFrame.Models
					player:PivotTo(plr.PlayerGui.Main.ViewportFrame.Lobby.Pads.MiddlePad.Location.CFrame)
					local nameClone = plr.PlayerGui.Main.Middle
					
					nameClone.name.Text = plr.DisplayName

					local ready = plr:WaitForChild("plrReady")

					if e.Name == "LittleDevYT2" then
						nameClone.dev.Visible = true
					end

					ready:GetPropertyChangedSignal("Value"):Connect(function()
						if ready.Value then
							nameClone.ready.Text = "Ready"
							nameClone.ready.TextColor3 = Color3.fromRGB(0, 255, 0)
							nameClone.ready.UIStroke.Color = Color3.fromRGB(73, 255, 79)
							task.wait(1)
							if workspace.plrsReady.Value == #game.Players:GetPlayers() then
								nameClone.ready.Text = "Joining"
								nameClone.ready.TextColor3 = Color3.fromRGB(255, 255, 255)
								nameClone.ready.UIStroke.Color = Color3.fromRGB(147, 147, 147)
							end
						else
							nameClone.ready.Text = "Not Ready"
							nameClone.ready.TextColor3 = Color3.fromRGB(255, 0, 0)
							nameClone.ready.UIStroke.Color = Color3.fromRGB(255, 90, 90)
						end
					end)


					workspace.plrsReady:GetPropertyChangedSignal("Value"):Connect(function()
						task.wait(1)
						if workspace.plrsReady.Value == #game.Players:GetPlayers() then
							nameClone.ready.Text = "Joining"
							nameClone.ready.TextColor3 = Color3.fromRGB(255, 255, 255)
							nameClone.ready.UIStroke.Color = Color3.fromRGB(147, 147, 147)
							task.wait(3)
							nameClone.ready.Text = "Failed to join"
							nameClone.ready.TextColor3 = Color3.fromRGB(255, 0, 0)
							nameClone.ready.UIStroke.Color = Color3.fromRGB(255, 90, 90)
						end
					end)
				elseif usedleftside == false then
					leftplayer = game.Players:GetPlayerFromCharacter(v)
					leftplayer.Name = v.Name.."Rig"
					local leftchar = v:Clone()
					leftchar.Parent = plr.PlayerGui.Main.ViewportFrame.Models
					leftchar:PivotTo(plr.PlayerGui.Main.ViewportFrame.Lobby.Pads.LeftPad.Location.CFrame)
					local nameClone = plr.PlayerGui.Main.Left

					local ready = leftplayer:WaitForChild("plrReady")
					
					nameClone.name.Text = leftplayer.DisplayName
					nameClone.name.Visible = true
					nameClone.ready.Visible = true

					if v.Name == "LittleDevYT2" then
						nameClone.dev.Visible = true
					end

					ready:GetPropertyChangedSignal("Value"):Connect(function()
						if ready.Value then
							nameClone.ready.Text = "Ready"
							nameClone.ready.TextColor3 = Color3.fromRGB(0, 255, 0)
							nameClone.ready.UIStroke.Color = Color3.fromRGB(73, 255, 79)
							task.wait(1)
							if workspace.plrsReady.Value == #game.Players:GetPlayers() then
								nameClone.ready.Text = "Joining"
								nameClone.ready.TextColor3 = Color3.fromRGB(255, 255, 255)
								nameClone.ready.UIStroke.Color = Color3.fromRGB(147, 147, 147)
							end
						else
							nameClone.ready.Text = "Not Ready"
							nameClone.ready.TextColor3 = Color3.fromRGB(255, 0, 0)
							nameClone.ready.UIStroke.Color = Color3.fromRGB(255, 90, 90)
						end
					end)


					workspace.plrsReady:GetPropertyChangedSignal("Value"):Connect(function()
						task.wait(1)
						if workspace.plrsReady.Value == #game.Players:GetPlayers() then
							nameClone.ready.Text = "Joining"
							nameClone.ready.TextColor3 = Color3.fromRGB(255, 255, 255)
							nameClone.ready.UIStroke.Color = Color3.fromRGB(147, 147, 147)
							task.wait(3)
							nameClone.ready.Text = "Failed to join"
							nameClone.ready.TextColor3 = Color3.fromRGB(255, 0, 0)
							nameClone.ready.UIStroke.Color = Color3.fromRGB(255, 90, 90)
						end
					end)
					usedleftside = true
				end

				leftplayer:GetPropertyChangedSignal("Parent"):Connect(function()
					usedleftside = false
					plr.PlayerGui.Main.Left.dev.Visible = false
					plr.PlayerGui.Main.Left.name.Visible = false
					plr.PlayerGui.Main.Left.ready.Visible = false
					leftplayer = nil
				end)
			elseif #game.Players:GetPlayers() == 3 then
				if v == e then
					local player = v:Clone()
					player.Name = e.Name.."Rig"
					player.Parent = plr.PlayerGui.Main.ViewportFrame.Models
					player:PivotTo(plr.PlayerGui.Main.ViewportFrame.Lobby.Pads.MiddlePad.Location.CFrame)
					local nameClone = plr.PlayerGui.Main.Middle
					
					nameClone.name.Text = plr.DisplayName

					local ready = plr:WaitForChild("plrReady")

					if e.Name == "LittleDevYT2" then
						nameClone.dev.Visible = true
					end

					ready:GetPropertyChangedSignal("Value"):Connect(function()
						if ready.Value then
							nameClone.ready.Text = "Ready"
							nameClone.ready.TextColor3 = Color3.fromRGB(0, 255, 0)
							nameClone.ready.UIStroke.Color = Color3.fromRGB(73, 255, 79)
							task.wait(1)
							if workspace.plrsReady.Value == #game.Players:GetPlayers() then
								nameClone.ready.Text = "Joining"
								nameClone.ready.TextColor3 = Color3.fromRGB(255, 255, 255)
								nameClone.ready.UIStroke.Color = Color3.fromRGB(147, 147, 147)
							end
						else
							nameClone.ready.Text = "Not Ready"
							nameClone.ready.TextColor3 = Color3.fromRGB(255, 0, 0)
							nameClone.ready.UIStroke.Color = Color3.fromRGB(255, 90, 90)
						end
					end)


					workspace.plrsReady:GetPropertyChangedSignal("Value"):Connect(function()
						task.wait(1)
						if workspace.plrsReady.Value == #game.Players:GetPlayers() then
							nameClone.ready.Text = "Joining"
							nameClone.ready.TextColor3 = Color3.fromRGB(255, 255, 255)
							nameClone.ready.UIStroke.Color = Color3.fromRGB(147, 147, 147)
							task.wait(3)
							nameClone.ready.Text = "Failed to join"
							nameClone.ready.TextColor3 = Color3.fromRGB(255, 0, 0)
							nameClone.ready.UIStroke.Color = Color3.fromRGB(255, 90, 90)
						end
					end)
				elseif usedleftside == false then
					leftplayer = game.Players:GetPlayerFromCharacter(v)
					leftplayer.Name = v.Name.."Rig"
					local leftchar = v:Clone()
					leftchar.Parent = plr.PlayerGui.Main.ViewportFrame.Models
					leftchar:PivotTo(plr.PlayerGui.Main.ViewportFrame.Lobby.Pads.LeftPad.Location.CFrame)
					local nameClone = plr.PlayerGui.Main.Left
					
					nameClone.name.Text = leftplayer.DisplayName
					nameClone.name.Visible = true
					nameClone.ready.Visible = true

					local ready = leftplayer:WaitForChild("plrReady")

					if v.Name == "LittleDevYT2" then
						nameClone.dev.Visible = true
					end

					ready:GetPropertyChangedSignal("Value"):Connect(function()
						if ready.Value then
							nameClone.ready.Text = "Ready"
							nameClone.ready.TextColor3 = Color3.fromRGB(0, 255, 0)
							nameClone.ready.UIStroke.Color = Color3.fromRGB(73, 255, 79)
							task.wait(1)
							if workspace.plrsReady.Value == #game.Players:GetPlayers() then
								nameClone.ready.Text = "Joining"
								nameClone.ready.TextColor3 = Color3.fromRGB(255, 255, 255)
								nameClone.ready.UIStroke.Color = Color3.fromRGB(147, 147, 147)
							end
						else
							nameClone.ready.Text = "Not Ready"
							nameClone.ready.TextColor3 = Color3.fromRGB(255, 0, 0)
							nameClone.ready.UIStroke.Color = Color3.fromRGB(255, 90, 90)
						end
					end)


					workspace.plrsReady:GetPropertyChangedSignal("Value"):Connect(function()
						task.wait(1)
						if workspace.plrsReady.Value == #game.Players:GetPlayers() then
							nameClone.ready.Text = "Joining"
							nameClone.ready.TextColor3 = Color3.fromRGB(255, 255, 255)
							nameClone.ready.UIStroke.Color = Color3.fromRGB(147, 147, 147)
							task.wait(3)
							nameClone.ready.Text = "Failed to join"
							nameClone.ready.TextColor3 = Color3.fromRGB(255, 0, 0)
							nameClone.ready.UIStroke.Color = Color3.fromRGB(255, 90, 90)
						end
					end)
					usedleftside = true
				elseif usedrightside == false then
					rightplayer = game.Players:GetPlayerFromCharacter(v)
					rightplayer.Name = v.Name.."Rig"
					local rightchar = v:Clone()
					rightchar.Parent = plr.PlayerGui.Main.ViewportFrame.Models
					rightchar:PivotTo(plr.PlayerGui.Main.ViewportFrame.Lobby.Pads.RightPad.Location.CFrame)
					local nameClone = plr.PlayerGui.Main.Right
					
					nameClone.name.Text = rightplayer.DisplayName
					nameClone.name.Visible = true
					nameClone.ready.Visible = true

					local ready = rightplayer:WaitForChild("plrReady")

					if v.Name == "LittleDevYT2" then
						nameClone.dev.Visible = true
					end

					ready:GetPropertyChangedSignal("Value"):Connect(function()
						if ready.Value then
							nameClone.ready.Text = "Ready"
							nameClone.ready.TextColor3 = Color3.fromRGB(0, 255, 0)
							nameClone.ready.UIStroke.Color = Color3.fromRGB(73, 255, 79)
							task.wait(1)
							if workspace.plrsReady.Value == #game.Players:GetPlayers() then
								nameClone.ready.Text = "Joining"
								nameClone.ready.TextColor3 = Color3.fromRGB(255, 255, 255)
								nameClone.ready.UIStroke.Color = Color3.fromRGB(147, 147, 147)
							end
						else
							nameClone.ready.Text = "Not Ready"
							nameClone.ready.TextColor3 = Color3.fromRGB(255, 0, 0)
							nameClone.ready.UIStroke.Color = Color3.fromRGB(255, 90, 90)
						end
					end)


					workspace.plrsReady:GetPropertyChangedSignal("Value"):Connect(function()
						task.wait(1)
						if workspace.plrsReady.Value == #game.Players:GetPlayers() then
							nameClone.ready.Text = "Joining"
							nameClone.ready.TextColor3 = Color3.fromRGB(255, 255, 255)
							nameClone.ready.UIStroke.Color = Color3.fromRGB(147, 147, 147)
							task.wait(3)
							nameClone.ready.Text = "Failed to join"
							nameClone.ready.TextColor3 = Color3.fromRGB(255, 0, 0)
							nameClone.ready.UIStroke.Color = Color3.fromRGB(255, 90, 90)
						end
					end)
					usedrightside = true
				end

				rightplayer:GetPropertyChangedSignal("Parent"):Connect(function()
					usedrightside = false
					rightplayer = nil
					plr.PlayerGui.Main.Right.dev.Visible = false
					plr.PlayerGui.Main.Right.name.Visible = false
					plr.PlayerGui.Main.Right.ready.Visible = false
				end)

				leftplayer:GetPropertyChangedSignal("Parent"):Connect(function()
					usedleftside = false
					leftplayer = nil
					plr.PlayerGui.Main.Left.dev.Visible = false
					plr.PlayerGui.Main.Left.name.Visible = false
					plr.PlayerGui.Main.Left.ready.Visible = false
				end)
			end
		end
	end
end)

Instead of using ViewportFrames, why not just make a rig for each position and hide them, then when a player joins, set the rigs skin to the one the player has. But the error you’re getting means that its trying to find the players parent, which is the Players Service, so you would have to change it to find the players character instead.

May you elaborate a little, on what line the error is happening and what function its happening on. Also if your getting any errors please share them as well.

Well, I’m using an emotes system that I made myself, and it would look like when Player1 is doing an emote, Player2 on their screen would see that he’s doing an emote when he didnt do anything. (I think) Also the error is at line 179.
Also for the emotes system, the post is: Buttons dont work .

I would try firing a function, or something to tell the other client that you played an animation and replicate it on their client. Try implementing something like that.