Why won't the part damage npc/players?

I’m making a gun thing, but when it creates a part it’s supposed to do damage, but it doesn’t with no errors.
Local Script (gun):

local Gui = script.Parent:WaitForChild("ScreenGui")
local Ammo = 4
local WaitTime = 1
local StoredAmmo = 3
local ShootPart = script.Parent.ShootPart
local mouse = game.Players.localPlayer:GetMouse()
script.Parent.Parent.Equipped:Connect(function(Mouse)
	        animation = game.Players.LocalPlayer.Character.Humanoid:LoadAnimation(script.Parent.Animation)
	   	   GuiClone = Gui:Clone()
	   	   GuiClone.Parent = game:GetService("Players").LocalPlayer.PlayerGui
	        animation:Play()
		   animation.Looped = true
end)
script.Parent.Parent.Activated:Connect(function(Mouse)
	  animation2 = game.Players.LocalPlayer.Character.Humanoid:LoadAnimation(script.Parent.Animation2)
	  GuiClone.Frame.TextLabel.Text = Ammo.."|"..StoredAmmo
	  GuiClone.Enabled = true
	  script.Parent.Sound:Play()
	  ammoCheck()
	  Ammo = Ammo - 1
	  shoot()
	  animation2:Play()
	  wait(WaitTime)
end)

script.Parent.Parent.Unequipped:Connect(function()
	 animation:Stop()
	 animation.Looped = false
	GuiClone.Enabled = false
end)
function reload()
	StoredAmmo = StoredAmmo - 1
	Ammo = 4
	animation3 = game.Players.LocalPlayer.Character.Humanoid:LoadAnimation(script.Parent.Animation3)
	animation3:Play()
	if StoredAmmo < 1 then
		GuiClone.Frame.TextLabel.Text = "No more ammo"
		wait(1.5)
		animation:Stop()
		animation2:Stop()
		GuiClone:Destroy()
		script.Parent.Parent:Destroy()
	end
end
function ammoCheck()
	if Ammo < 1 then
		reload()
	end
end
function shoot()
	local Bullet = Instance.new("Part", workspace)
	Bullet.Size = Vector3.new(0.3, 0.05, 0.1)
	Bullet.BrickColor = BrickColor.new("New Yeller")
	Bullet.Material = Enum.Material.Neon
	Bullet.Position = ShootPart.Position
	Bullet.Name = "Bullet"
	local Force = Instance.new("BodyVelocity")
	for count = 1,2 do
		Bullet.CFrame = CFrame.new(mouse.hit.p) + Vector3.new(0,1,0)
	end
	wait(2)
	Bullet:Destroy()
end
function onKeyPress(inputObject, gameProcessedEvent)
	if inputObject.KeyCode == Enum.KeyCode.R then
		reload()
	end
end
game:GetService("UserInputService").InputBegan:connect(onKeyPress)

Script (part):

local Brick = game.Workspace:WaitForChild("Bullet")
local function PlayerTouched(hit)
	local Parent = hit.Parent
	if hit.Parent:FindFirstChild("Humanoid") then
		Parent.Humanoid.Health = Parent.Humanoid.Health - 10
	end
end

Brick.Touched:connect(PlayerTouched)
1 Like

Try something like to this:

script.Parent.Touched:Connect(function(hit) 
	if hit.Parent:FindFirstChild("Humanoid") then
		hit.Parent.Humanoid.Health = hit.Parent.Humanoid.Health - 10 
		print(hit.Name)
	end
end)
2 Likes

I tried

script.Parent.Touched:Connect(function(hit) 
	if hit.Name == "Bullet" then
		if hit.Parent:FindFirstChild("Humanoid") then
			hit.Parent.Humanoid.Health = hit.Parent.Humanoid.Health - 10 
			print(hit.Name)
		end
	end
end)

no errors, and doesn’t work. I had to change it a bit because I was checking an Instance.new part

1 Like

Your error is that you’re creating a part (the bullet) locally and you’re expecting the server to find it. Due to FilteringEnabled, the server can’t see the parts that are created locally. You’d want to create it on the server. Perhaps you can send a remote event to the server telling it to create the bullet part.


Debugging 101: How to avoid these kinds of problems in the future
When debugging, it’s a good idea to put print statements (known as debug statements) around in the code because when you have no errors, one very common problem is that part of the code isn’t running!

With debug statements, you can verify some data is stored as expected and scripts are running as expected. If you put a simple debug statement printing anything below the line in the server script where you waited for the bullet, I believe you’d find that it never prints because the server never finds the bullet as the WaitForChild() is bound to yield the thread forever.

3 Likes
  • Touched won’t work if parts and CFramed into each other.
  • You are setting the bullet to the same CFrame twice.
  • I see that you are making a BodyVelocity and not doing anything with it.
  • Look at @Asinphi’s post. Also, the client won’t be able to change another person’s health (Huh, I tried it, and the person does die, but only on the killer’s client. Interesting.).

Consider using raycasting to do damage
https://developer.roblox.com/en-us/articles/Raycasting

You will also need a remove event.
https://developer.roblox.com/en-us/articles/Roblox-Client-Server-Model

2 Likes

Expanding on the raycasting part, I’d personally highly recommend the FastCast module for ranged projectile damage. It can simulate bullet physics with gravity, acceleration, and the such.

As for why RayCasting is a superior method than Touched events, Touched can prove itself particularly unreliable for small, fast-moving projectiles (which are what bullets are, essentially).

1 Like