Hello,
I made some crossbows recently but I’ve ran into a problem that I solved but in an inefficient way and I’m here to see if there’s a better way to check if something is a child of the character with out adding multiple if’s to check if the parent is an accessory or a model etc etc, here’s the script if it helps, Any help is appreciated.
Damage script:
if hit.Parent:FindFirstChild("Humanoid") then
print("Player")
local char = hit.Parent
print("In Radius")
hit.Parent:FindFirstChild("Humanoid"):TakeDamage(damage)
char.Head.Hit:Play()
elseif hit.Parent:IsA("Accessory") or hit.Parent:IsA("Hat") then
local char = hit.Parent.Parent
char.Humanoid:TakeDamage(damage)
char.Head.Hit:Play()
end
Depending on how fast your arrow flies, you might want to stay away from Touched (if it’s fast). It’s better to use a physics simulation and detect hits with raycasts. This post might give you some pointers.
Regardless of what you use, you can’t really get around having if-checks. If your characters are the default characters (or you are certain that you never put a model inside them), this snippet will give you the humanoid object from a part:
local hum = hit:FindFirstAncestorWhichIsA("Model"):FindFirstChildWhichIsA("Humanoid")
If you need the character model, make sure to use hum.Parent as hum will be nil if the part is not part of a character (so you can get away with a single if-check: if hum then).
You can still edit this code with the line I provided to shorten it down by a bit.
local hum = hit:FindFirstAncestorWhichIsA("Model"):FindFirstChildWhichIsA("Humanoid")
if hum then
hum:TakeDamage(damage)
hum.Parent.Head.Hit:Play()
end
Remember that this (but also your) code would error if the character doesn’t have a head; make sure that can never happen or add another if-check making sure it’s there before indexing it.
In that example the sword would deflect a bullet if it hits the sword straight on, if you use my code at least. A sword would probably just slice through the player anyway so it’s no big deal.
In that case you would either want to loop through all existing characters, or use recursion/iteration to get to the bottom-most model that has a humanoid inside it.
I’d do the latter since it seems like the appropiate solution for an event that can happen multiple times per second.
local m = hit.Parent
while not m:FindFirstChild("Humanoid") and m.Parent ~= game do
m = m.Parent
end
local hum = m:FindFirstChild("Humanoid")