Attempt to index nil with findfirstchild even though it exists

I’m working on a weapon class for a game, and am trying to get the HumanoidRootPart of the hit humanoid and the attackers humanoid. When I print out these they work fine, but when I use findfirstchild to index them it throws nil? Apologies if this post is confusing I’m super tired writing this

function Gauntlet:OnHit(humanoid, damage)
	if self._hitdebounce then return end
	if humanoid.Parent.RagdollTrigger.Value == true then return end
	if humanoid.Parent.Parent:FindFirstChildOfClass("ForceField") then return end
	
	print(humanoid)
	print(humanoid.Parent)
	
	local root = humanoid.Parent:FindFirstChild("HumanoidRootPart")
	local myRoot = self.character:FindFirstChild("HumanoidRootPart")
	
	self._hitdebounce = true
	
	humanoid:TakeDamage(damage)
	
	if root and not root.Anchored and myRoot then
		local delta = root.Position - myRoot.Position
		root:SetNetworkOwner(nil)
		humanoid.Parent.RagdollTrigger.Value = true
		root:ApplyImpulse(delta.unit * self.config.KNOCKBACK_STRENGTH_X + Vector3.new(0, self.config.KNOCKBACK_STRENGTH_Y, 0))
	end
	
	task.wait(2)
	self._hitdebounce = false
end
1 Like

Try using WaitForChild(), that might work

1 Like

Are you sure the error is coming from humanoid.Parent:FindFirstChild? Looks to me like you do not check self.character and call FindFirstChild on that as well.

Try using WaitForChild(), that might work

This will not work if the error is attempt to index nil with FindFirstChild. That means that you are running the equivalent of nil:FindFirstChild(something).

1 Like

Oh my bad i didnt realize that

1 Like

I tried printing self.character and it prints nil, I don’t understand cause I use it in my constructor function and it works fine, I guess other functions aren’t able to index the character that’s used in the constructor function? I don’t understand. I’m finding the character of the tool using this:

local function findCharacter(path)
	local plr = path.Parent.Parent
	local char = plr.Character or plr.CharacterAdded:Wait()
	
	return char
end

Should I just use this again instead of referencing the one used in my constructor function?

1 Like

Also my constructor function looks something like this:

function Gauntlet.new(tool, config)
	local self = setmetatable({}, Gauntlet)

	self.tool = tool
	self.character = findCharacter(tool)
	
	return self
end
1 Like

Are you calling OnHit with a dot? Or with a Touched event perhaps? In either case, ‘self’ isn’t provided automatically.

2 Likes

I use a module called clientcast for hit detection and this is how I call the onhit function:

self._clientcaster.HumanoidCollided:Connect(function(result, hitHum)
	Gauntlet:OnHit(hitHum, self.config.DAMAGE)
end)
1 Like

FWIW if the issue was self being nil, then the initial if self._hitdebounce check would have errored.

2 Likes

Aha. Is Gauntlet a class instance or just the class? If it’s just the class, then self.character won’t exist.

1 Like

I’m kind of confused, why wouldn’t the character exist? I get self.character from the tools parent, which should always be a character. Is there a better way to do this?

1 Like

Gauntlet.new() returns a Gauntlet instance.

Gauntlet is just the class.

local gauntlet = Gauntlet.new(tool, character)
gauntlet:OnHit(humanoid, damage) -- will work!
Gauntlet:OnHit(humanoid, damage) -- using the class, will not work!

Is self in your case the gauntlet? If so you can try self:OnHit(hitHum, self.config.DAMAGE).

4 Likes

Oh my gosh, I just realized what I did wrong. I literally used self instead of gauntlet on every function except this one, woops!

1 Like