So I’ve coded a gun, which casts a ray to the player’s mouse, and detects if it hits a humanoid, which is pretty simple. It works pretty good so far, however there was one strange issue that I ran into.
I’ve also created a zombie AI. When I shoot the zombie’s head or torso with my gun, it deals the proper amount of damage it’s supposed to. But for some reason, the raycast can’t seem to hit the arms or legs?? I’ve tried to print the raycast, and whenever I aim directly at the legs/arms, it always says “nil”.
What’s even weirder is that when I anchor any part of the zombie, I am for some reason able to shoot the arms and legs and it works like it’s supposed to. Any help would be greatly appreciated!
eventsFolder.Fire.OnServerEvent:Connect(function(player, mousePos, mouseTarget)
if not cooldown then
if ammo.Value >= 1 then
ammo.Value -= 1
cooldown = true
spawn(function()
wait(gunSettings.firerate)
cooldown = false
end)
script.Events.CameraFlick:FireClient(player, gunSettings.recoil)
muzzleFlash()
animations.Fire:Play()
if fireSoundNum == 1 then
fireSoundNum = 2
sounds.Fire1:Play()
elseif fireSoundNum == 2 then
fireSoundNum = 1
sounds.Fire2:Play()
end
local spread = Vector3.new(math.random(-gunSettings.spread, gunSettings.spread), math.random(-gunSettings.spread, gunSettings.spread), math.random(-gunSettings.spread, gunSettings.spread)) / 10
local rParams = RaycastParams.new()
rParams.RespectCanCollide = true
rParams.FilterDescendantsInstances = {character, weapon}
rParams.FilterType = Enum.RaycastFilterType.Blacklist
local ray = workspace:Raycast(weapon.Frame.BulletExit.WorldPosition, ((mousePos + spread) - weapon.Frame.BulletExit.WorldPosition).Unit * 5000, rParams)
if ray ~= nil then
if ray.Instance ~= nil then
local hit = ray.Instance
if hit.Parent:FindFirstChildWhichIsA("Humanoid") then
rParams.FilterDescendantsInstances = {character, weapon, ray.Instance.Parent}
local ray2 = workspace:Raycast(mousePos + spread, weapon.Frame.BulletExit.WorldPosition - (mousePos + spread), rParams)
if ray2 == nil then
local hum = ray.Instance.Parent:FindFirstChildWhichIsA("Humanoid")
local damage = damageSettings.other
print(hit)
if hit.Name == "Head" then
damage = damageSettings.head
playHitSound(hit, sounds.bulletImpact.HeadShot)
elseif string.match(hit.Name, "Torso") or hit.Name == "HumanoidRootPart" then
damage = damageSettings.torso
playHitSound(hit, sounds.bulletImpact.TorsoShot)
elseif string.match(hit.Name, "Arm") or string.match(hit.Name, "Leg") then
playHitSound(hit, sounds.bulletImpact.LimbShot)
damage = damageSettings.limb
else
playHitSound(hit, sounds.bulletImpact.MiscShot)
end
bloodSplatter(ray.Position)
hum:TakeDamage(damage)
if hum.Health <= 0 and hit.Name == "Head" then
local bv = Instance.new("BodyVelocity")
bv.P = math.huge
bv.MaxForce = Vector3.new(math.huge, math.huge, math.huge)
bv.Velocity = hit.CFrame.LookVector * -30
bv.Parent = hit
game.Debris:AddItem(bv, 0.2)
hit.Parent.Torso.Neck:Destroy()
end
if damageSettings.bleeding then
spawn(function()
wait(0.5)
for i = 1, math.random(5, 9), 1 do
if hum.Health > 0 then
bloodSplatter(hit.Position)
hum:TakeDamage(damage * damageSettings.bleedPercentage)
wait(0.8)
end
end
end)
end
end
else
hitResidue(ray.Position, hit.Color)
end
end
end
end
end
end)
I dont think it has anything to do with the problem, but heres why: A raycast wont detect a part if it is raycasted inside of that part. So if a player puts their gun inside of a wall, then they could shoot through that wall. I use a second ray to cast back from where the first ray hit to make sure that there are no parts intersecting with the gun and the target.
Well, the fact that it’s even printing nil when you shoot the arms means that the ray cast is detecting the left arm, since it will only get to that part if ray.Instance ~= nil. There must be something going on after that line, so try printing to the output right after that conditional statement to see if the part really is nil, or if there’s something causing that part to go nil in the client. I’m guessing this piece of code is placed in a local script, so it might have to do something to do with server-client replication.
Since something is causing the part to become nil even though the part shouldn’t be nil according to the conditional statement, that means the second ray cast could indeed have something to do with the issue.
When you anchor the character, you’re anchoring the character on the client, but not on the server. This is why the code suddenly works, because now the part you’re working with is going to stay the exact same on the client. I’m guessing that’s where the problem stems from, but it could definitely be something else.
Edit: Anchoring on the server should do the same thing. The character is no longer moving, so the limbs aren’t changing anymore, and there can’t be any server-client replication issues when the parts aren’t even changing.