Hey devforum! I have a module function that is supposed to handle player spawning, but sometimes setupPlayer isn’t called, other times the character isn’t repositioned, etc. Help is greatly appreciated, since my game doesn’t work without this function
function module.handlePlayerLoading(spawnL, extras, team, otherFunc)
spawnL.Enabled = true
local function onCharacter(plr, char)
local hrp = char:FindFirstChild("HumanoidRootPart")
if not hrp then
hrp = char:WaitForChild("HumanoidRootPart", 3)
end
if hrp and spawnL then
task.wait(0.3)
hrp.CFrame = spawnL.CFrame * CFrame.new(0, 3, 0)
print("Repositioned", plr.DisplayName)
else
warn("Failed to reposition " .. plr.Name)
end
end
local function setupPlayer(plr)
plr.Neutral = false
hideLoadingEV:FireClient(plr)
if team then
plr.Team = team
end
if otherFunc then
pcall(function()
otherFunc(plr)
end)
end
plr.CharacterAdded:Connect(function(char)
onCharacter(plr, char)
end)
if plr.Character then
onCharacter(plr, plr.Character)
else
plr:LoadCharacter()
end
end
for _, plr in pairs(Players:GetPlayers()) do
setupPlayer(plr)
end
Players.PlayerAdded:Connect(setupPlayer)
end
The code seems rather complicated in certain parts. It may also be better to utilize MoveTo rather than change the RootPart’s Coordinate Frame to spawn the player. Something else I’m sort of confused about is why the code rather than a SpawnLocation?
Anywho, let’s go through this.
When you supply a timeout for WaitForChild it will check if the object exists. You can simply do
local hrp = char:WaitForChild("HumanoidRootPart", 3)
Since spawnL is required in the beginning instructions (before onCharacter setup) it’s redundant to check if it’s truthy.
You could simply set it to team or the player’s current team.
plr.Team = team or plr.Team
You could have pcall simply call otherFunc without needing an anonymous function to wrap it.
pcall(otherFunc, plr)
It may be better to connect PlayerAdded before running through the players.
To fix the problem, there’s a couple of things you could try:
A) Use CharacterAppearanceLoaded, or
B) Use MoveTo to move the player’s character to that location. There’s also apparently something called PivotTo which may be handy.
Yeah, there’s a method of the exact same name intended for the Humanoid, but there’s one for the Model class. One’s like alright walk over there ^ - ^ while the other’s like you move now **uses godly powers to move your very being**
Just a slight suggestion, but it may also be worth adjusting the upwards CFrame to account for the player’s height. Just so that it doesn’t look kind funny seeing a larger avatar partially in the ground for a split second lol. This can be accomplished with GetModelCFrame.
local hrp = char:WaitForChild("HumanoidRootPart", 3)
local heightAdjustment = char:GetModelCFrame().Y / 2
heightAdjustment = CFrame.new(0, heightAdjustment, 0)
if hrp then
hrp.CFrame = spawnL.CFrame * heightAdjustment
else
char:PivotTo(char:GetPivot() * heightAdjustment)
end
Or for those who prefer non-deprecated methods,
local hrp = char:WaitForChild("HumanoidRootPart", 3)
local _, heightAdjustment = char:GetBoundingBox()
heightAdjustment = CFrame.new(0, heightAdjustment.Y / 2, 0)
if hrp then
hrp.CFrame = spawnL.CFrame * heightAdjustment
else
char:PivotTo(char:GetPivot() * heightAdjustment)
end