FindFirstChild doesn't seem to be working

I’m making a phone script and my script works fine except for when I use findfirstchild to find a cloned audio within the part.

It can’t seem to find the objects despite the fact they do exist under where I’m calling from and so does the object I’m calling from.

StartCallEvent.OnServerEvent:Connect(function(player, phoneNumber, phoneFrom)
	local recieivingPhone: Model = nil
	local callingPhone: Model = nil
	
	for i, v in pairs(PhoneNumbers) do
		if not v:GetAttribute("isCalling") then
			if i == phoneNumber then
				local RingAudioClone = RingAudio:Clone()
				RingAudioClone.Parent = v.Part
				RingAudioClone.Name = "Ring"
				RingAudioClone:Play()
				recieivingPhone = v
			end

			if v.Name == phoneFrom and recieivingPhone ~= nil then
				local DialAudioClone = DialAudio:Clone()
				DialAudioClone.Parent = v.Part
				DialAudioClone.Name = "Dial"
				DialAudioClone:Play()
				callingPhone = v
			end
		end
	end
	
	
	if recieivingPhone ~= nil and callingPhone ~= nil then
		recieivingPhone:SetAttribute("isCalling", true)
		recieivingPhone:SetAttribute("CallingWho", callingPhone.Name)
		callingPhone:SetAttribute("isCalling", true)
		callingPhone:SetAttribute("CallingWho", recieivingPhone.Name)
		
		StartCallEvent:FireAllClients(recieivingPhone, callingPhone)
	end
	
end)

UpdateCallEvent.OnServerEvent:Connect(function(player, response: boolean, phoneSentTo, phoneFrom)
	local callingPhone = nil

	for _, v in PhoneNumbers do
		if v.Name == phoneFrom then
			callingPhone = v
			break
		end
	end

	local firstPickupPrompt: ProximityPrompt = phoneSentTo.Part:FindFirstChild("PickupPrompt")
	local firstHangupPrompt: ProximityPrompt = phoneSentTo.Part:FindFirstChild("HangupPrompt")
	local secondPickupPrompt: ProximityPrompt = callingPhone.Part:FindFirstChild("PickupPrompt")
	local secondHangupPrompt: ProximityPrompt = callingPhone.Part:FindFirstChild("HangupPrompt")

	if response then
		firstPickupPrompt.Enabled = false
		firstHangupPrompt.Enabled = true
	else
		firstHangupPrompt.Enabled = false
		firstPickupPrompt.Enabled = false
		secondPickupPrompt.Enabled = false
		secondHangupPrompt.Enabled = false
		
		print(phoneSentTo.Part:GetChildren())
		print(callingPhone.Part:GetChildren())

		local FoundRingAudio = phoneSentTo.Part:FindFirstChild("Ring")
		local FoundDialAudio = callingPhone.Part:FindFirstChild("Dial")
		
		
		FoundRingAudio:Stop()
		FoundDialAudio:Stop()
		FoundDialAudio:Destroy()
		FoundRingAudio:Destroy()
	end
end)

AHHHHHHH

1 Like

If you’re cloning the audio right after FindFirstChild is called then it will spat out an error. So I guess you could use WaitForChild.

WaitForChild doesn’t work either. And I don’t check for the child DIRECTLY after it. It’s only after the player pushes hang up that it will check for audio

Ok so about the audio cloning part.

local RingAudioClone = RingAudio:Clone()
RingAudioClone.Parent = v.Part
RingAudioClone.Name = "Ring"
RingAudioClone:Play()

Try putting the .Parent code before the :Play()

local RingAudioClone = RingAudio:Clone()
RingAudioClone.Name = "Ring"
RingAudioClone.Parent = v.Part
RingAudioClone:Play()

Done, but no change

for i, v in pairs(PhoneNumbers) do
		if not v:GetAttribute("isCalling") then
			if i == phoneNumber then
				local RingAudioClone = RingAudio:Clone()
				RingAudioClone.Name = "Ring"
				RingAudioClone.Parent = v.Part
				RingAudioClone:Play()
				recieivingPhone = v
			end

			if v.Name == phoneFrom and recieivingPhone ~= nil then
				local DialAudioClone = DialAudio:Clone()
				DialAudioClone.Name = "Dial"
				DialAudioClone.Parent = v.Part
				DialAudioClone:Play()
				callingPhone = v
			end
		end
	end

Alright, So what exactly is throwing error here?

Is the problem being calling FindFirstChild returns nil?

1 Like

Yep, that’s the error! It returns null for some strange reason

You can’t just clone() and parent an object then just call FindFirstChild..
Try this:

StartCallEvent.OnServerEvent:Connect(function(player, phoneNumber, phoneFrom)
	local recieivingPhone: Model = nil
	local callingPhone: Model = nil
	
	for i, v in pairs(PhoneNumbers) do
		if not v:GetAttribute("isCalling") then
			if i == phoneNumber then
				local RingAudioClone = RingAudio:Clone()
				RingAudioClone.Parent = v:FindFirstChild("Part")
				RingAudioClone.Name = "Ring"
				RingAudioClone:Play()
				recieivingPhone = v
			end

			if v.Name == phoneFrom and recieivingPhone ~= nil then
				local DialAudioClone = DialAudio:Clone()
				DialAudioClone.Parent = v:FindFirstChild("Part")
				DialAudioClone.Name = "Dial"
				DialAudioClone:Play()
				callingPhone = v
			end
		end
	end
	
	if recieivingPhone ~= nil and callingPhone ~= nil then
		recieivingPhone:SetAttribute("isCalling", true)
		recieivingPhone:SetAttribute("CallingWho", callingPhone.Name)
		callingPhone:SetAttribute("isCalling", true)
		callingPhone:SetAttribute("CallingWho", recieivingPhone.Name)
		
		StartCallEvent:FireAllClients(recieivingPhone, callingPhone)
	end
end)

UpdateCallEvent.OnServerEvent:Connect(function(player, response: boolean, phoneSentTo, phoneFrom)
	local callingPhone = nil

	for _, v in PhoneNumbers do
		if v.Name == phoneFrom then
			callingPhone = v
			break
		end
	end

	local firstPickupPrompt: ProximityPrompt = phoneSentTo:FindFirstChild("Part"):FindFirstChild("PickupPrompt")
	local firstHangupPrompt: ProximityPrompt = phoneSentTo:FindFirstChild("Part"):FindFirstChild("HangupPrompt")
	local secondPickupPrompt: ProximityPrompt = callingPhone:FindFirstChild("Part"):FindFirstChild("PickupPrompt")
	local secondHangupPrompt: ProximityPrompt = callingPhone:FindFirstChild("Part"):FindFirstChild("HangupPrompt")

	if response then
		firstPickupPrompt.Enabled = false
		firstHangupPrompt.Enabled = true
	else
		firstHangupPrompt.Enabled = false
		firstPickupPrompt.Enabled = false
		secondPickupPrompt.Enabled = false
		secondHangupPrompt.Enabled = false
		
		print(phoneSentTo:FindFirstChild("Part"):GetChildren())
		print(callingPhone:FindFirstChild("Part"):GetChildren())

		local FoundRingAudio = phoneSentTo:FindFirstChild("Part"):FindFirstChild("Ring")
		local FoundDialAudio = callingPhone:FindFirstChild("Part"):FindFirstChild("Dial")
		
		if FoundRingAudio then
			FoundRingAudio:Stop()
			FoundRingAudio:Destroy()
		end
		if FoundDialAudio then
			FoundDialAudio:Stop()
			FoundDialAudio:Destroy()
		end
	end
end)

Ok make sure whatever Part that you’re indexing has a unique name for it. If any of your other Parts has the same “Part” name.

maybe you can change it to “SoundPart”

Tried that, nothing changed about the error.

Also tried this, nothing changed about it either

What about this one? I’ve been seeing the code and I think this one is possible to work.. also added prints so you can debug. Never forget to debug to check errors!

StartCallEvent.OnServerEvent:Connect(function(player, phoneNumber, phoneFrom)
	local recieivingPhone: Model = nil
	local callingPhone: Model = nil
	
	for i, v in pairs(PhoneNumbers) do
		if not v:GetAttribute("isCalling") then
			if i == phoneNumber then
				local RingAudioClone = RingAudio:Clone()
				RingAudioClone.Parent = v:FindFirstChild("Part")
				RingAudioClone.Name = "Ring"
				RingAudioClone:Play()
				recieivingPhone = v
			end

			if v.Name == phoneFrom and recieivingPhone ~= nil then
				local DialAudioClone = DialAudio:Clone()
				DialAudioClone.Parent = v:FindFirstChild("Part")
				DialAudioClone.Name = "Dial"
				DialAudioClone:Play()
				callingPhone = v
			end
		end
	end
	
	if recieivingPhone ~= nil and callingPhone ~= nil then
		recieivingPhone:SetAttribute("isCalling", true)
		recieivingPhone:SetAttribute("CallingWho", callingPhone.Name)
		callingPhone:SetAttribute("isCalling", true)
		callingPhone:SetAttribute("CallingWho", recieivingPhone.Name)
		
		StartCallEvent:FireAllClients(recieivingPhone, callingPhone)
	end
end)

UpdateCallEvent.OnServerEvent:Connect(function(player, response: boolean, phoneSentTo, phoneFrom)
	local callingPhone = nil
	local receivingPhone = nil

	for _, v in PhoneNumbers do
		if v.Name == phoneFrom then
			callingPhone = v
		end
		if v.Name == phoneSentTo then
			receivingPhone = v
		end
	end

	if not callingPhone or not receivingPhone then
		return
	end

	local firstPickupPrompt: ProximityPrompt = receivingPhone:FindFirstChild("Part"):FindFirstChild("PickupPrompt")
	local firstHangupPrompt: ProximityPrompt = receivingPhone:FindFirstChild("Part"):FindFirstChild("HangupPrompt")
	local secondPickupPrompt: ProximityPrompt = callingPhone:FindFirstChild("Part"):FindFirstChild("PickupPrompt")
	local secondHangupPrompt: ProximityPrompt = callingPhone:FindFirstChild("Part"):FindFirstChild("HangupPrompt")

	if response then
		firstPickupPrompt.Enabled = false
		firstHangupPrompt.Enabled = true
	else
		firstHangupPrompt.Enabled = false
		firstPickupPrompt.Enabled = false
		secondPickupPrompt.Enabled = false
		secondHangupPrompt.Enabled = false
		
		print(receivingPhone:FindFirstChild("Part"):GetChildren())
		print(callingPhone:FindFirstChild("Part"):GetChildren())

		local FoundRingAudio = receivingPhone:FindFirstChild("Part"):FindFirstChild("Ring")
		local FoundDialAudio = callingPhone:FindFirstChild("Part"):FindFirstChild("Dial")
		
		if FoundRingAudio then
			FoundRingAudio:Stop()
			FoundRingAudio:Destroy()
		end
		if FoundDialAudio then
			FoundDialAudio:Stop()
			FoundDialAudio:Destroy()
		end
	end
end)

I already send the model from phoneSentTo due to how my server works (i for loop the phoneFrom as that’s saved to an attribute). Also, you haven’t changed much of the script and it would theoretically work the same

I did change it, and also added debug. Can you tell me what printed from the debug? The logs
And make sure the args in FindFirstChild actually exist tho, there are people including me that mistake that.
And if it doesn’t work and you already checked they exist then try giving us the entire code.
You can also try replacing FindFirstChild with WaitForChild, it’s more efficient for these type of scripts
But firstly I’m gonna try to fix the script. Do you mind waiting?

I don’t mind. But it’s getting late so I might be asleep by the time you’re done!

I think I already know the problem..
If the phones are Models and the “main part” is inconsistent, the safe way is to use PrimaryPart instead of “hardcoding” "Part".
So instead of

RingAudioClone.Parent = v:FindFirstChild("Part")

try using

RingAudioClone.Parent = v.PrimaryPart

Idk, this is an idea. If it has PrimaryPart this can help instead of FindFirstChild, considering that it’s unefficent

I found the issue! I was sending in the attribute wrong in my other scripts. Previously the attribute was put in the phoneFrom parameter (which is reserved for the phone that hangs up). When it should have been in the phoneSentTo parameter

It’s great that you solved it alone! I knew there was something wrong with the outside of the script considering getting the attribute

2 Likes