Why is my code to find the local character not working anymore?

I’ve used this code for months and it worked every time. Now, it no longer does.

local player = game.Players.LocalPlayer
local character = game.Players.LocalPlayer.CharacterAdded:wait() or game.Players.LocalPlayer.Character
local torso = character:WaitForChild("HumanoidRootPart")
local hum = character:WaitForChild("Humanoid")

What the code it is in does is basically wait for the humanoid to fire Humanoid.Died, then it sends it over to a remote event which handles leaderstats. The script works properly on the first death, but after that it fails to work all the time. It doesn’t detect the character. Why is this?

8 Likes
local player = game.Players.LocalPlayer
local character = player.Character or player.CharacterAdded:Wait()
local torso = character:WaitForChild("HumanoidRootPart")
local hum = character:WaitForChild("Humanoid")

switch around your character line. you are calling :Wait() even if it’s already added.

Also, if you want this to work after respawn, put it in StarterCharacterScripts

8 Likes

If it has to be inside StarterPlayerScripts, use the player.CharacterAdded event to get the character, torso, and humanoid again after re-spawning with a new character.

player.CharacterAdded:Connect(function(char)
character = char
torso = character:WaitForChild("HumanoidRootPart")
hum = character:WaitForChild("Humanoid")
end)
2 Likes

I am not sure why it is not working. I myself would not write a code that way. @Fm_Trick’s way does work, and it is like yours. If I had to remake the script itself, my code would be something like this:

-- Variables --

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Event = ReplicatedStorage:WaitForChild("AddLeaderstatsDeath") -- Event

local Players = game:GetService("Players")
local Player = Players.LocalPlayer

local Character = Player.Character

repeat wait() until Character ~= nil

local HumanoidRootPart = Character:WaitForChild("HumanoidRootPart")
local Humanoid = Character:WaitForChild("Humanoid")

-- Scripting --

Humanoid.Died:connect(function()
	Event:FireServer()
end)

This is how I would code the event to be fired. Also, the code above only runs StarterGui, and if put in a ScreenGui, the ScreenGui must have ResetOnSpawn enabled, else it will not work. If you are looking to put it anywhere else, then I recommend using the Player.CharacterAdded function and then setting the character, else if you want to have a plain script in StarterGui that resets every time you die and does the work, then my script would work. If you want something else, then I recommend @Fm_Trick’s and @PowerPig609’s scripts as they work perfectly fine.

1 Like

No need to complicate things, I can see the main issue was just to switch player.Character and player.CharacterAdded:Wait(), as demonstrated by @Fm_Trick.

1 Like

I did that already, didn’t work.

Switching the two expressions around in a LocalScript under PlayerScripts doesn’t work because PlayerScripts don’t refresh and the variable isn’t redefined after it’s evaluated on the first call.

Not enough information is being provided. Where is your script? What explicitly is your script trying to accomplish? StarterCharacterScripts could be an acceptable alternative.

local player = game.Players.LocalPlayer
repeat wait() until player.Character
local character = player.Character

Just wait for the character to be added

That’s what OP is doing right now. Again, this won’t work (and in fact is much more strange, because you’re reinventing the wheel here - CharacterAdded:Wait() yields until the character is found).

The point is that if the script is in a container that doesn’t refresh, then this is only going to evaluate once and not again (the problem OP is facing). You need to handle respawn cases yourself or put it in a container that does refresh when a new spawn is signaled.

1 Like

If the character is already added Character added:Wait() doesn’t fire so his script will solve this issue. CharacterAdded is an event.

That’s not the issue of the thread though.

If character already exists, it will use the character. If it doesn’t, the line will wait until CharacterAdded fires which returns the arguments passed to it (the character). Both evaluate to the character.

OP is having issues with detecting the character after the first run of the script. It works once, then not again. The issue is that the script still assumes use of the old character variable’s value, which is now nil (and a memory leak, because a reference is being held to the character and now it won’t be gced - unless Destroy is called on the backend for new spawns).

For the purposes of this thread, the aforementioned code is moot. And, once again, there’s no reason to reinvent the wheel with a repeat loop when CharacterAdded exists.

The character model you get by indexing Player.Character is replaced when re-spawning and you need to fetch the new instance. You also seem to have switched around the direct index and the Wait call.

Yeah, but what I’m wondering is why this code is no longer working. It has worked perfectly fine for me before. I’ve also tried moving the code around from starterplayerscripts to startergui to starterpack, but nothing.

“The issue is that the script still assumes use of the old character variable’s value, which is now nil (and a memory leak, because a reference is being held to the character and now it won’t be gced - unless Destroy is called on the backend for new spawns).” - colbert2677

I now realize that the variable is static and doesn’t refresh. I’ll create a function every time characteradded is called and will update the character variable to the argument given. Thanks!

1 Like

Have you really tried everything you could?

Assuming that your character variable isn’t being updated, that means that the script isn’t being refreshed on spawn. You can test this by writing a simple repro that runs code per spawn.

Code I’m working with:

print("Stack!")

local HttpService = game:GetService("HttpService")
local Players = game:GetService("Players")
local Character = Players.LocalPlayer.Character or Players.LocalPlayer.CharacterAdded:Wait()
local UniqueIdentifier = HttpService:GenerateGUID()

print("Container:", script.Parent)
print("Unique Identifier", UniqueIdentifier)
print("TEST:", Character, Character.Parent)

I’ve placed this script in four relevant containers:
image
Note: If it’s in StarterCharacterScripts, the container will show up as my username because scripts from there are cloned and inserted into my character.

First spawn:

Second spawn:

Third spawn:

So on, so forth.

I still don’t know your original implementation sicne it was vaguely included in the main thread (you never specified what script type you were using, nor where the script was or anything). So, with that in mind, this is all I can offer you - a test showing LocalScript usage.

I’ve got no idea what’s going on with Backpack. Probably an err with my test.

Don’t be dependent on this kind of maintainability. Things on the platform change. Just because something worked before, doesn’t necessarily imply it’ll still work (of course, that’s circumstantial).

You’re reinventing the wheel here, it may not even be necessary to handle respawns depending on what it is that you’re running.

1 Like