I had some trouble with my local script, located in the StarterPlayerScript, as It would not execute when I’ve spawned. I’ve finally come to a solution; here’s the code →
wait()
local player = game.Players.LocalPlayer
local character = player.Character
if not character or not character.Parent then
character = player.CharacterAdded:Wait()
end
My question is if there is a more efficient or better way of doing this, suggestions would be appreciated.
local player = game.Players.LocalPlayer
local Character = player.Character or player.CharacterAdded:Wait() --If player.Character is nil then it will wait for CharacterAdded event to fire because of :Wait()
I mean the only time this would not work is when player respawns, which in that case you can just connect it to CharacterAdded event but what do you mean by you have to use wait() to make the script execute? Are you changing client’s cameraType or something?
An easy solution to this would be to put the script in StarterCharacterScripts instead of StarterPlayerScripts
In StarterCharaterScripts, the script executes only once the character instance has been added.
If you absolutely cannot put the script there, you can always assume the player will load before the character, because it’s not possible to have a character without having a player instance first. I would edit your script to have as few yields as possible. Getting rid of the first wait() you have will ensure that the script initializes before the character is added. So your script should look something like this in the end:
local player = game.Players.LocalPlayer
player.CharacterAdded:Connect(function(character)
--Do stuff with character instance here, this will only fire once the character has been added
end))
If I don’t place the wait() function at the beginning of the local script, then everything after the function would not take action when I spawn my character.
Something is definitely wrong then. Have you tried placing prints or using the debugger to see exactly where it halts? Maybe you’re trying to wait for the character after it’s already spawned or have some other yielding method.
wait()
local player = game.Players.LocalPlayer
local character = player.Character
if not character or not character.Parent then
character = player.CharacterAdded:Wait()
end
local hum = character:FindFirstChild("Humanoid")
if hum then
print("Humanoid found")
while wait(1.2) do
hum.Jump = true
print("Start jumping")
end
end
I see your issue. Instead of :FindFirstChild do :WaitForChild and remove the wait at the top.
The reason you had to wait() before was because the humanoid does not load at the same time as the character and gets added after the character is added.
The optimal layout for this script would be a script in StarterCharacterScripts which contains the following
local Character = script.Parent -- because the script will be a decendant of the character if placed under StarterCharacterScripts
local Humanoid = Character:WaitForChild("Humanoid") -- wait for the humanoid to get added
while wait(1.2) do
Humanoid.Jump = true
print("Jumped")
end
I got a warning, and it still doesn’t execute. Oh, I thought script.Parent would be the Character for some reason. Be right back. I think you’ve paved the path for me to find a solution to this.
Infinite yield possible on 'Players.Tixabel.PlayerScripts:WaitForChild(“Humanoid”)
Did you put the script in StarterCharacterScripts or StarterPlayerScripts? Make sure its in StarterCharacterScripts otherwise you’ll be trying to look for the humanoid inside of the PlayerScripts folder which wont work.
local Players = game:GetService("Players")
local player = Players.LocalPlayer or Players:GetPropertyChangedSignal("LocalPlayer"):wait()
player.CharacterAdded:Wait()
local character = player.Character
local hum = character:WaitForChild("Humanoid")
while wait(1.2) do
hum.Jump = true
print("Start jumping")
end
Found a solution without using the wait() function at the beginning of the script
just to point out, you can also update the character and humanoid variable through player.CharacterAdded event and it should work again after the character Instance is destroyed.
edit: same goes for localscripts located in StarterPack
local Players = game:GetService("Players")
local player = Players.LocalPlayer or Players:GetPropertyChangedSignal("LocalPlayer"):wait()
player.CharacterAdded:Connect(function(character)
local hum = character:WaitForChild("Humanoid")
while wait(1.2) do
hum.Jump = true
print("Start jumping")
end
end)
Thanks for pointing out, now I’ll be more aware to not rely on wait() functions alone by any means necessary
Don’t forget to call the function in CharacterAdded if the player.Character exists!
Also made a few edits that I think would improve your code.
So like this:
local Players = game:GetService("Players")
local player = Players.LocalPlayer -- no need to wait for LocalPlayer
local function onCharacterAdded(character)
-- I prefer a little more verbose variables.
local humanoid = character:WaitForChild("Humanoid")
-- while wait() do isn't the best practice. Use the condition of while x do to check if character and
-- humanoid exist
while character and humanoid do
wait(1.2)
-- Possible bug since the character may not exist after 1.2 seconds, even though we did a check.
-- Not a big deal since it simply errors, but if you'd like to remove some random errors.
if not character then
break
end
if not humanoid then
break
end
humanoid.Jump = true
print("Start jumping")
end
end
if player.Character then
-- You should probably use FastSpawn instead of coroutines if you want good errors
coroutine.wrap(onCharacterAdded)(player.Character)
end
player.CharacterAdded:Connect(onCharacterAdded)
This has some unnecessary code. Neither the loop condition nor loop body need to check character and humanoid. Since these are local variables, they only change when explicitly set by the user.
Thanks, @Autterfly, for the information. The link above clarifies what you say; the only time LocalPlayer is necessary to yield would be if the local script were located in the ReplicatedFirst. The LocalScript can sometimes run before the LocalPlayer is available, so it needs to be yielded.