Infinite Wait when waiting for LocalCharacter, etc

I have a loadstring calling to a module script (via pastebin w/ HttpGet, so I can use it across games), and within that module script there are local variables, such as:

local plr = game:GetService'Players'.LocalPlayer
local char = plr.Character
local hrp = char.HumanoidRootPart

When these are loaded, theres an error saying they are calling to a nil value. See, to fix the nil problem I had the script utilize a waiting call to the first line. The line is as follows:

repeat task.wait() until game:IsLoaded() and game:GetService'Players':WaitForChild'LocalPlayer'

The pattern above (WaitForChild) continues with the instances of the variables defined, I’m too lazy to type the rest lf those variables out as I am on mobile and it is 6am. (I have not slept because I want to solve this.)

I have also alterntively used FindFirstChild, and used its 2nd arg (so it utilizes descendants) to skip to searching for the HumanoidRootPart. No errors, just never loads and the script utilizing it never progresses. Previously, this script was working just fine, but when I tested it in a laggier environment (multiple clients), the nil errors occured, so I added a wait.

3 Likes

Correct me if I’m wrong, but aren’t you supposed to include brackets with GetService?

local plr = game:GetService(“Players”).LocalPlayer
1 Like

You can use it without, I never use brackets and I just use ’ because it takes less time, unless multiple arguments are needed.

1 Like

LocalPlayer is a variable not a child, its directly available using the dot syntax

2 Likes

I did not know that, but that makes a lot more sense. Should I instead do

workspace:WaitForChild(game:GetService'Players'.LocalPlayer.Name)

to check for the character? (As in, would it be more effieicent or is there a shorter alternative?)

1 Like

Bad practice. Using task.wait() with repeat to wait for code is called polling and it’s much less efficient than anything event based. And combined with :FindFirstChild() and a recursive search it wastes much more resources than necessary.

LocalPlayer reference is available right away before any local scripts run, so you can index safely. For the rest, I would use :WaitForChild().

local player = game:GetService'Players'.LocalPlayer
local char = player.Character or player.CharacterAdded:Wait()
local hrp = char:WaitForChild'HumanoidRootPart'

Character is not a model inside a player, but a property pointing to the model that appears in workspace. Until then, it is nil.

2 Likes

Is there a more efficient way you know of (with an event) to wait until the game is loaded to resume the script?

2 Likes

Sure, I usually use this somewhere in my projects:

if not game:IsLoaded() then
    game.Loaded:Wait()
end
1 Like

Doesnt this just stop the script and wait forever if the game isn’t loaded?

It checks if the game is loaded already. If it was an we called :Wait(), it would indeed yield, but because of this clause it’s only going to wait if the game is not loaded yet. I’m successfully using this all the time.

Ohhhh, that flew way over my head, thanks!

1 Like

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