:FindFirstAncestor and :IsDescendantOf don't work for some reason?

right, bullets, guns, they’re all cool and stuff

damage is dealt based whether the player hits the body or the head (aka, headshot and bodyshot damage)

but some enemies (like the one seen in the video), have gore elements that are NOT called “Head” or limb names like “Torso”

to get around this, i decided to use :FindFirstAncestor() and IsDescendantOf(), but for some reason it just doesn’t work?

function DealDamage(result: RaycastResult, character: Model, humanoid: Humanoid, bodyshotDamage: number, headshotDamage: number)
	if players:GetPlayerFromCharacter(character) then return end
	if not humanoid then return end
	
	local damageDealt = nil
	
	if result.Instance == character.Head or result.Instance:FindFirstAncestor("Head") or result.Instance:IsDescendantOf("Head") then
		humanoid:TakeDamage(headshotDamage)
		damageDealt = headshotDamage
		
	elseif result.Instance ~= character.Head then
		for _,bodyPart  in validLimbs do
			if result.Instance:IsDescendantOf(bodyPart) or result.Instance:FindFirstAncestor(bodyPart) then
				humanoid:TakeDamage(bodyshotDamage)
				damageDealt = bodyshotDamage
				break
			end
		end
	end
	
	return damageDealt
end

visual presentation:


oh and here are the hierarchies of the limbs that i’ve hit:
image

1 Like

try a few print methods such as

print(result.Instance)
print(result.Instance == character.Head)
tell me what those print

also show me what ‘validLimbs’ looks like, i wanna see the contents of the table

1 Like

the print statements only run if i don’t shoot the gore elements, what…?
(and the second print statement will print true if it’s the head of course)

not sure why that happens?

-- Tables;
local validLimbs = {
	"Left Arm",
	"Right Arm",
	"Left Leg",
	"Right Leg",
	"Torso"
}

-- Functions;
function DealDamage(result: RaycastResult, character: Model, humanoid: Humanoid, bodyshotDamage: number, headshotDamage: number)
	if players:GetPlayerFromCharacter(character) then return end
	if not humanoid then return end
	
	local damageDealt = nil
	
	if result.Instance == character.Head or result.Instance:FindFirstAncestor("Head") or result.Instance:IsDescendantOf("Head") then
		humanoid:TakeDamage(headshotDamage)
		damageDealt = headshotDamage
		
	elseif result.Instance ~= character.Head then
		for _,bodyPart  in validLimbs do
			if result.Instance:IsDescendantOf(bodyPart) or result.Instance:FindFirstAncestor(bodyPart) then
				humanoid:TakeDamage(bodyshotDamage)
				damageDealt = bodyshotDamage
				break
			end
		end
	end
	
	print(result.Instance)
	print(result.Instance == character.Head)
	
	return damageDealt
end

try replace:
if result.Instance:IsDescendantOf(bodyPart) or result.Instance:FindFirstAncestor(bodyPart) then

WITH

if result.Instance:IsDescendantOf(character[bodyPart]) or result.Instance:FindFirstAncestor(bodyPart) then

IsDescendantOf takes an Instance parameter, whereas FindFirstAncestor takes in a string parameter. So to make the bodypart an instance, we just index character with it.

this didn’t fix it, unfortunately

what the hell is going on??

:FindFirstAncestor and :IsDescendantOf are functionally the same, with the only difference being the arguments. :FindFirstAncestor requires the argument to be a string, while :IsDescendantOf takes the argument as an Instance. You’ve got some of these mixed up.

So your issue is, those print statements only run if you DON’T shoot the gore elements. Do the gore elements have CanQuery = true? and show me the raycasting section of the code please

yes

function Raycasting(origin: Part, player: Player, hitPos: Mouse, weapon: Tool)
	local HEADSHOT_DAMAGE = gunInfo[weapon.Name]["HEADSHOT_DAMAGE"]
	local BODYSHOT_DAMAGE = gunInfo[weapon.Name]["BULLET_DAMAGE"]

	-- Raycast parameters. 	
	local raycastParams = RaycastParams.new()
	raycastParams.FilterType = Enum.RaycastFilterType.Exclude
	raycastParams.FilterDescendantsInstances = {player.Character}
	raycastParams.IgnoreWater = true

	local direction = (hitPos - origin.Position).Unit
	local displacement = direction * gunInfo[weapon.Name]["MAX_DISTANCE"]
	local result = workspace:Raycast(
		origin.Position,
		displacement,
		raycastParams
	)

	local endPos = nil

	-- Did the raycast hit something?
	if result then
		endPos = result.Position
		
		local character: Model = result.Instance.Parent
		local humanoid: Humanoid = character:FindFirstChildOfClass("Humanoid")
		
		local damageDealt: number = DealDamage(result, character, humanoid, BODYSHOT_DAMAGE, HEADSHOT_DAMAGE)
		
		if damageDealt == nil then return end
		
		damageIndicatorEvent:FireClient(player, damageDealt, humanoid)
	else
		endPos = origin.Position + displacement
	end
end

Is your issue.

If the gore part is a child of Head. then the character would be result.Instance.Parent.Parent, therefore the humanoid would be nil, not running the function at all

Try:
local humanoid: Humanoid = result.Instance.Parent:FindFirstChildOfClass(“Humanoid”) or result.Instance.Parent.Parent:FindFirstChildOfClass(“Humanoid”)
locla character: Model = humanoid and humanoid.Parent

(note, result.Instance.Parent.Parent can be nil so make sure to check for this too)

a bit messy, but it should fix it

i have some neeewwsss for youuu

it DOESN’T fix it :sob:

what am i doing wrongggg

function Raycasting(origin: Part, player: Player, hitPos: Mouse, weapon: Tool)
	local HEADSHOT_DAMAGE = gunInfo[weapon.Name]["HEADSHOT_DAMAGE"]
	local BODYSHOT_DAMAGE = gunInfo[weapon.Name]["BULLET_DAMAGE"]

	-- Raycast parameters. 	
	local raycastParams = RaycastParams.new()
	raycastParams.FilterType = Enum.RaycastFilterType.Exclude
	raycastParams.FilterDescendantsInstances = {player.Character}
	raycastParams.IgnoreWater = true

	local direction = (hitPos - origin.Position).Unit
	local displacement = direction * gunInfo[weapon.Name]["MAX_DISTANCE"]
	local result = workspace:Raycast(
		origin.Position,
		displacement,
		raycastParams
	)

	local endPos = nil

	-- Did the raycast hit something?
	if result then
		endPos = result.Position
		
		local humanoid: Humanoid = result.Instance.Parent:FindFirstChildOfClass("Humanoid")
		local character: Model = humanoid and humanoid.Parent
		
		if result.Instance.Parent.Parent == nil then return end
		
		local damageDealt: number = DealDamage(result, character, humanoid, BODYSHOT_DAMAGE, HEADSHOT_DAMAGE)
		
		if damageDealt == nil then return end
		
		damageIndicatorEvent:FireClient(player, damageDealt, humanoid)
	else
		endPos = origin.Position + displacement
	end
end

Replace these lines with this:

local humanoid: Humanoid = result.Instance.Parent:FindFirstChildOfClass(“Humanoid”) or result.Instance.Parent.Parent:FindFirstChildOfClass(“Humanoid”)
locla character: Model = humanoid and humanoid.Parent

1 Like

omg i love you
i love you i love you

i looooveeee youuuu

thank you!!!

1 Like