Player = nil when checking for children?

So I have this script that when touched, should take the food crate (if they have it) give a count value and untransparency a few parts. But it gives me an error at the part where it checks if the player has the food crate in the backpack or character, or even at all. any help?

hit = nil

script.Parent.Touched:Connect(function(hit)

if hit and hit.Parent and hit.Parent:FindFirstChild("Humanoid") then

local player = game.Players:GetPlayerFromCharacter(hit)

local crate = hit:FindFirstChild("Food Crate") or player.Backpack:FindFirstChild("Food Crate")

if crate then

script.Parent.Parent.Count.Value = 3

script.Parent.Parent.Steak1.Wrapper.Transparency = 0.7

script.Parent.Parent.Steak1.SteakRaw.Transparency = 0

script.Parent.Parent.Steak2.Wrapper.Transparency = 0.7

script.Parent.Parent.Steak2.SteakRaw.Transparency = 0

script.Parent.Parent.Steak3.Wrapper.Transparency = 0.7

script.Parent.Parent.Steak3.SteakRaw.Transparency = 0

crate:Destroy()

hit = nil

end

end

end)
1 Like

What does the error say? (30 characters)

Workspace.Model.FoodTouchPart.Script:6: attempt to index global ‘player’ (a nil value)

Replace that with this:

local player = game.Players:GetPlayerFromCharacter(hit.Parent)

In a Touched event, the argument passed in is the basepart that touched.

Same here:

hit.Parent:FindFirstChild("Food Crate")

The reason why you are getting this error is because you are passing the wrong thing through the :GetPlayerFromCharacter(). At the moment you are passing the hit part into the function which will be the characters feet. The way you fix this problem is by passing the actual character model through the function by doing :GetPlayerFromCharacter(hit.Parent). Here is the line fixed:

local player = game.Players:GetPlayerFromCharacter(hit.Parent)

As a little nit pick you should try and always indent your code and avoid putting spaces between each line. This will help other people read your code easier when solving issues with it. You should also always use local variables where you can:

local hit = nil

script.Parent.Touched:Connect(function(hit)
	if hit and hit.Parent and hit.Parent:FindFirstChild("Humanoid") then
		local player = game.Players:GetPlayerFromCharacter(hit.Parent)
		local crate = hit:FindFirstChild("Food Crate") or player.Backpack:FindFirstChild("Food Crate")
		if crate then
			script.Parent.Parent.Count.Value = 3
			script.Parent.Parent.Steak1.Wrapper.Transparency = 0.7
			script.Parent.Parent.Steak1.SteakRaw.Transparency = 0
			script.Parent.Parent.Steak2.Wrapper.Transparency = 0.7
			script.Parent.Parent.Steak2.SteakRaw.Transparency = 0
			script.Parent.Parent.Steak3.Wrapper.Transparency = 0.7
			script.Parent.Parent.Steak3.SteakRaw.Transparency = 0
			crate:Destroy()
			hit = nil
		end
	end
end)

Piggybacking off of this you should try to localize your objects. Instead of using
script.Parent.Parent continuously, try to create variables instead. local steakContainer instead of script.Parent. This will make your code much easier to read and also easier to keep track of.

2 Likes

Because, you’re using hit as the Player Character, but that just the part that is getting hit, so, hit.Parent m8.