"Attempt to call method 'FindFirstChild' (a nil value)"

Heyo,

I’ve been developing a game recently and one feature I’d like to implement are custom nametags for all the NPCs in the World.

From this:

To this:

Instead of manually adding this in, I want to instead make a script that would automatically add those nametags as well as hide the existing ones using arrays (in case I add lots of NPCs)

Pseudocode:
1. Get children from workspace
2. If child is a Model, get the model's children
3. Look for Humanoid and Head (to determine it is an NPC)
4a. If nametag exists, return end
4b. If nametag isn't created, create the nametag under Head
5. Hide default nametag

Code:

--Makes custom nametags for all Humanoids
local Wk = game:GetService("Workspace")
local Hm = Wk:GetChildren()

while true do
	wait(0)
	for m = 1, #Hm do
		if Hm[m].ClassName == "Model" then
			local AF = Hm[m]:GetChildren()
			
			local Headtag = AF:FindFirstChild("Head").Nametag --The Problematic line
			
			if Headtag then
				return
			else
				if AF.Humanoid ~= nil then
					if AF.Head ~= nil then
						AF.Humanoid.DisplayDistanceType = "None"
						local Tag = Instance.new("BillboardGui",Hm[m]:findFirstChild("Head"))
						Tag.Name = "Nametag"
						Tag.ExtentsOffset = Vector3.new(0,2,0)
						Tag.MaxDistance = 25
						Tag.LightInfluence = 0
						
						local Nme = Instance.new("TextLabel", Tag)
						Nme.Name = "Namebox"
						Nme.BackgroundTransparency = 1
						Nme.TextSize = 25
						Nme.TextColor3 = Color3.new(255,255,255)
						Nme.Font = "Cartoon"
						Nme.Text = (Hm.Name)
					else
						print(script.Name.." > No Head found.")
					end
				else
					print(script.Name.." > No Humanoid found.")
				end
			end
		end
	end
end

All I get is an “attempt to call method ‘FindFirstChild’ a nil value
Same thing happens when I use WaitForChild as well.

I’m not the best at scripting, nor using arrays.

Aand it’s my first time posting something to the forums :sweat:

I created code based off the pseudo code which you provided and this is how it turned out:

for _, object in ipairs(workspace:GetChildren()) do
	local head = object:FindFirstChild("Head")
	local humanoid = object:FindFirstChildWhichIsA("Humanoid")
	if head and humanoid then
		humanoid.DisplayDistanceType = Enum.HumanoidDisplayDistanceType.None
		if not head:FindFirstChild("Nametag") then
			-- create name tag
		end
	end
end

The reason you are receiving an error is because you are attempting to use FindFirstChild on an array. You should instead search for a head and name tag in the object rather than call GetChildren on it, here is an example:

local Head = Hm[m]:FindFirstChild("Head")
local Humanoid = Hm[m]:FindFirstChildWhichIsA("Humanoid")
if Head and Humanoid then
    Humanoid.DisplayDistanceType = Enum.HumanoidDisplayDistanceType.None
    if not Head:FindFirstChild("Nametag") then
        -- create name tag
    end
end
8 Likes

The problem is when you get AF, you are getting a table since :GetChildren returns a table. Since you can’t use FindFirstChild() on a table, it thinks that you are trying to index a function inside of the table called FindFirstChild. Try using AF[“Head”].Nametag instead.

4 Likes

Another thing, FindFirstChild is a Roblox function, not a Lua function, and you can only use that function on Roblox objects. Here, AF is an array of all children of Hm[m], not a Roblox object, so you cannot use FindFirstChild on it. Instead, normal indexing would do just fine.

1 Like