Creator Tag not working

Hey! I tried to make it so when a player dies, it checks if it has a creator tag, and gets the value of the creator tag. I tried and tested it and it does not reward the killer that killed the player. How can I fix this?

Here is my script:

player.CharacterAdded:Connect(function(char)
		local humanoid = char:WaitForChild("Humanoid")
		humanoid.Died:Connect(function()
			Deaths.Value = Deaths.Value + 1
			local tag = humanoid:FindFirstChild("creator")
			local killer = tag.Value
			if tag and killer then
				killer.leaderstats:FindFirstChild("Kills").Value += 1
				killer:FindFirstChild("RoundKills").Value += 1
			end
		end)
	end)

The code is placed in a function, and the function is played when a player joins.

Help soon,

papahetfan

Just by looking at what you said about the rewarding not working for the killer, and a quick glimpse of the code, I can think of a few solutions.

The first thing is, we set ‘tag’ to a :FindFirstChild(“creator”) as shown below:

local tag = humanoid:FindFirstChild("creator")

And then below, you instantly set killer to ‘tag.Value’ without actually reassuring that tag actually is an object (as at this point, :FindFirstChild() could have returned nil).

local tag = humanoid:FindFirstChild("creator")
local killer = tag.Value -- For all we know, tag could be nil, and nil doesn't have a .Value property.

Then we go to the condition, which checks:

if tag and killer then

Which means, if tag isn’t nil and killer isn’t nil, then we run the code in the condition. At a guess, either tag or killer are nil (if tag is the one that’s nil, of course killer will be too).

The most reliable way to determine if an object exists is to use :WaitForChild() with a timeout (so it doesn’t wait infinitely for an object to be found) and then handle accordingly what happens in the eventuality that returned object is nil.

player.CharacterAdded:Connect(function(char)
	local humanoid = char:WaitForChild("Humanoid", 2)
	if humanoid then
		humanoid.Died:Connect(function()
			Deaths.Value = Deaths.Value + 1
			
			local tag = humanoid:WaitForChild("creator", 2)
			if not tag then
				--[[ We could construct a new object to put in the humanoid here, 
				but will error and return here as we can't continue. ]]
				error("Failed to find "creator" object in the Humanoid.")
				return
			end
			
			local killer = tag.Value
			if tag and killer then
				killer.leaderstats:FindFirstChild("Kills").Value += 1
				killer:FindFirstChild("RoundKills").Value += 1
			end
		end)
	end
end)

So overall, my guess as to why it doesn’t work is because tag is nil, so won’t get into the condition, it’s probably erroring on the local killer = tag.Value line, saying that there’s no .Value property of nil.

Let me know if it works and if you have any questions. :slight_smile:

Thank you. I’ll let you know if there is any bugs.

Based on previously given code to you, the tag data was a string. Use Players:FindFirstChild(tag.Value)

Oop, good shout. Completely bypassed he was trying to find objects in a string. I’ll correct my code, I apologise entirely, it’s half past midnight okay. :sob:

Alright, based on @04nv’s comment, this code should do the trick. What we do different is, we use tag.Value to get the player by finding a Player in the current players playing. Otherwise, we just do constant checks to see if each object is valid at that point in time, returning/stopping the code if the objects don’t exist (which is up to you in how you want to handle these cases).

-- Assuming you have this line already, but we need it to access the Players service.
local Players = game:GetService("Players")

player.CharacterAdded:Connect(function(char)
	local humanoid = char:WaitForChild("Humanoid", 2)
	if humanoid then
		humanoid.Died:Connect(function()
			Deaths.Value = Deaths.Value + 1
			
			local tag = humanoid:WaitForChild("creator", 2)
			if not tag then
				--[[ We could construct a new object to put in the humanoid here, 
				but will error and return here as we can't continue. ]]
				error("Failed to find "creator" object in the Humanoid.")
				return
			end
			
			--[[ This was returning a string here, we need to get the player object of the killer!
			We can also use :FindFirstChild() here as the player should almost definitely exist here.]]
			local killer = Players:FindFirstChild(tag.Value) 
			if tag and killer then
			
				-- Leaderstats may not exist, so we'll find this properly too.
				local leaderstats = killer:WaitForChild("leaderstats", 2)
				if not leaderstats then
					error("Failed to find leaderstats folder in the killer.")
					return
				end
				
				--[[ From this point, we should be certain that the values in leaderstats will
				exist, but we'll use :FindFirstChild() anyway. ]]
				local killsValueObj = leaderstats:FindFirstChild("Kills")
				if not killsValueObj then
					error("Failed to find the 'Kills' object in the leaderstats folder.")
					return
				end
				killsValueObj.Value += 1
				
				-- Same with the round kills.
				local roundKillsObj = killer:FindFirstChild("RoundKills")
				if not roundKillsObj then
					error("Failed to find the 'RoundKills' object in the killer.")
					return
				end
				roundKillsObj.Value += 1
			end
		end)
	end
end)
1 Like

It works! Thank you so much! Also thank you to @04nv for helping!

1 Like