While coding I came across an interesting behaviour
It’s common practice to use the following to get the character of a player:
local Player = P.LocalPlayer
local Character = Player.Character or Player.CharacterAdded:Wait()
I thought to myself “Why even use Player.Character when it is near always nil and then immediately jumps to Player.CharacterAdded:Wait()” and wrote this:
local Player = P.LocalPlayer
local Character = Player.CharacterAdded:Wait()
This forever yields and never returns the character. Why does the first option work and not the second?
Player.CharacterAdded runs once when the character is added. If your code is executed after the character has been added, it will wait forever, or until the player respawns and gets a new character.
When the script is in StarterCharacterScripts, of course the character is always going to be already loaded in so the following code works:
local Player = P.LocalPlayer
local Character = Player.Character
print("StarterCharacter: "..Character.Name)
Because it’s no different than accessing the character with:
local Character = script.Parent
However when the script is in StarterPlayerScripts, naturally the character isn’t already going to be loaded in so the following works:
local Player = P.LocalPlayer
local Character = Player.CharacterAdded:Wait()
print("StarterPlayer: "..Character.Name)
So in summary:
StarterPlayerScripts:local Character = Player.CharacterAdded:Wait() StarterCharacterScripts:local Character = Player.Character or local Character = script.Parent StarterPlayerScripts & StarterCharacterScripts:local Character = Player.Character or Player.CharacterAdded:Wait()