So I have a remote event that gets fired from the server once my character gets added, sending that character as a parameter. However, once it reaches the client, the character is nil.
Server Code:
local PLAYERS = game:GetService("Players")
local CHAR_ADDED = game.ReplicatedStorage.CharAdded
PLAYERS.PlayerAdded:Connect(function(player)
player.CharacterAdded:connect(function(character)
print(player, character)
CHAR_ADDED:FireAllClients(player, character)
end)
end)
Client Code:
local CHAR_ADDED = game.ReplicatedStorage.CharAdded
CHAR_ADDED.OnClientEvent:Connect(function(player, character)
print(player, character)
end)
Instances are passed by reference through remotes. If the client sees an instance variable as nil that means it doesn’t exist on the client yet. The current internal instructions for character loading does not guarantee an existing character when CharacterAdded fires.
Characters are created by the server so they will not immediately exist on the client until they’re attached to the DataModel. If you add an additional print to check the parent of the character from the server you’ll see that when CharacterAdded fires the parent is nil. There are three ways to resolve this, in order from most ideal to less ideal:
Defer FireAllClients. This will need a bit of testing but it should defer until LoadCharacter returns whether called internally or by developer code. Not particularly sure where it gets slotted.
Use AncestryChanged to check if the character has been attached to the DataModel.
From the server using the second method:
local PLAYERS = game:GetService("Players")
local CHAR_ADDED = game.ReplicatedStorage.CharAdded
PLAYERS.PlayerAdded:Connect(function(player)
player.CharacterAdded:connect(function(character)
task.defer(CHAR_ADDED.FireAllClients, CHAR_ADDED, player, character)
end)
end)
I don’t suggest using a method like this. It would be much better if you handle CharacterAdded on each client separately.
i.e.
local function HandleCharacter(Character)
-- do whatever
end
local function HandlePlayer(Player)
if Player.Character then HandleCharacter(Player.Character) end
Player.CharacterAdded:Connect(HandleCharacter)
end
for _, Player in ipairs(game.Players:GetPlayers()) do
HandlePlayer(Player)
end
game.Players.PlayerAdded:Connect(HandlePlayer)