Hi I’m kind of new to making scripts that are relative to waiting before loading data, or stats. This is some code I whipped up that runs a function when the player’s character is in the game.
game.Players.PlayerAdded:Connect(function(player)
repeat wait() until player.Character or player == nil
morph(player.userId,character)
player.CharacterAppearanceLoaded:Connect(function(character)
morph(player.userId,character)
end)
end)
All I want to know is if there’s a better way to do this, and what the method is.
There is a much better way to do this. If you’re waiting for the character to load, you can do it in a more efficient variable.
local character - player.Character or player.CharacterAdded:Wait()
This will only yield if the player’s character doesn’t exist yet, and when the character loads, it will stop yielding.
It’s not a good idea to have the player becoming nil as the condition, because if they do become nil, then your script would error, because the player wouldn’t be found.
If we are being picky here, it wouldn’t matter if you did or did not have Player == nil seeming as the Character is going to load before the Player is removed anyway as the CharacterAdded event was already fired on the Player joining unless its disabled - also if you checked Player.Parent it would be the game.Players which is basically irrelevant in this scenario.
I think we’re all forgetting the fact that we’re not fully sure how Roblox has adapted Garbage Collection and that scripts etc are pretty instantaneous relative to us and their will be an order within events that the server handles, i.e. the Character will likely be added if calls before the server handles removes the Player.
In regards to your efficiency in your method, I think the key thing I’ll point out is the fact your morphing your character twice essentially - once when Player.Character is not nil i.e. the Player model exists and is set to the character and once when the entirety of the characters appearance has loaded - in other words you would be better just cutting out:
repeat wait() until player.Character or player == nil
morph(player.userId,character)
Is going to fire the moment the Player’s Character has fully loaded - this method is good if you want to make certain everything in the Character is deleted etc if your trying to remove accessories for example.
Your methodology is fine however, wouldn’t do much different myself aside from removing the thing above.
BAD. Never, ever use a while wait() or repeat wait() code, as it can easily introduce lag into your game. I would recommend using a wait(numberHere) when possible.
Putting that aside, I have a set of solutions:
If you want to have a variable the also keeps the character, and have a method of garbage collection, use local character = player.Character or player.CharacterAdded:Wait(). If the character is nil, it will call yielding function CharacterAdded:Wait(), which returns the character model.
If you just want to wait for the character, use: workspace:WaitForChild(player.Name).
I used to use repeat wait() until player.Character in the old days, but it’s just inefficient, lag-inducing, and ugly.
Using local character = player.Character or player.CharacterAdded:Wait() is generally the most professionally used method on Roblox, but the variable does not get “garbage collected”, meaning you have to have some workarounds. If you want to check if your character still exists, I would use:
local doesExist = character and character.Parent and character:FindFirstChild("Humanoid")
Keep in mind that having something like if soandso, the code knows you are implying *if soandso~=nil`. The following code is what the engine sees that works EXACTLY the same, but is not necessarily needed to write:
local doesExist = character ~= nil and character.Parent ~= nil and character:FindFirstChild("Humanoid") ~= nil
hi I was wondering if u could help me with my problem as well.
I have a boolvalue call no steal and when u press a button it makes the bool value true, everything seems to work but when it comes to the dunking it breaks. Im not familiar with using repeat so I was wondering if u can tell me what I did wrong or rewrite it.
This is my code:
FixBallEvent.OnServerEvent:Connect(function(player, NoSteal, Ball)
if NoSteal == true then
local character = player.Character
local humanoid = character:WaitForChild(“Humanoid”)
Ball.Equip.Disabled = false
Ball.Ball.Position = character.PrimaryPart.Position
Ball.Ball.Velocity = Vector3.new(0, -1, 0)
wait(1)
if player.NoSteal.Value == true then
Ball.Equip.Disabled = false
Ball.Ball.Position = character.PrimaryPart.Position
wait(1)
repeat wait(1) until player:FindFirstChild(“Ball”)
wait(2)
humanoid.Climbing = true
humanoid.WalkSpeed = 16
Ball.Equip.Disabled = true
end
end
end)
So basically when I press a button the bool value sets itself to true which disables a script from happening. when I dunk the ball I made I fire client that leads to that script to happen but the ball doesn’t return to the player and im trying to make it loop until the ball is found in the player. its hard to explain…