How to make a sword not deal damage to player but to NPC?

Pretty much stated it in the title. I tried looking around on YouTube and the devforum, but nothing was helping. Although the sword would deal damage to npc’s.

local hit = --Humanoid Character your sword hit
local players  = game.Players:GetPlayers()

local isPlayer = false
for i, player in pairs(players) do
    if player.Character == hit then isPlayer = true break end
end

if isPlayer then
   print("It was a player")
else
   print("It was an npc")
   --deal damage to npc
end

What would I put there? I am not that good at scripting so I am kind of dumb with this.

assuming your sword is just a part

local sword = --sword

local hit = nil

sword.Touched:Connect(function(p)
   if p.Parent.FindFirstChild("Humanoid") then 
      hit = p.Parent
   end
   --You can put rest of the code here if you want
end)

As in the code that you replied first?

yes, complete code:


local sword = script.Parent--sword
local damage = 69

local TimeBetweenHit = .5 --0.5 seconds between damages

local debounce = false

sword.Touched:Connect(function(hit)
    if debounce then return end
	if hit.Parent:FindFirstChild("Humanoid") then 
		hit = hit.Parent
	else
		return
	end

	local players  = game.Players:GetPlayers()

	local isPlayer = false
	for i, player in pairs(players) do
		if player.Character == hit then isPlayer = true break end
	end

	if isPlayer then
		print("It was a player")
	else
		print("It was an npc")
		hit.Humanoid.Health -= damage
        debounce = true
        wait(TimeBetweenHit )
        debounce = false
	end

end)
1 Like

You better use.

sword.Touched:Connect(function(hit)
	if not game:GetService("Players"):GetPlayerFromCharacter(hit.Parent) then return end
end)
4 Likes

Should add a debounce as well, I edit it now

1 Like

Like @UniDevx mentioned, it would be a better practice to use the GetPlayerFromCharacter function to determine whether the part you’ve hit belongs to a Player. This will be faster and more performant than using a for-loop to iterate through the player list as was done in @robloxgamerzys 's code

in practice, you could write it like so:

-- Services
local Players = game:GetService('Players')

-- Variables
local sword -- Assign this to the part you want to use to detect collisions 
local Damage = 20
local debounces = {}

sword.Touched:Connect(function(hit)
	local Player = Players:GetPlayerFromCharacter(hit.Parent)
	if not Player then 
		return
	end
	
	local Humanoid = Player.Character:FindFirstChildOfClass('Humanoid')
	
	if Humanoid then
		-- Debounce hit detection
		if table.find(debounces, Player) then
			return
		end
		table.insert(debounces, Player)
		
		-- Deal damage
		Humanoid:TakeDamage(Damage)
		
		-- Let debounce run out
		task.wait(0.1)
		table.remove(debounces, table.find(debounces, Player))
	end
end)
2 Likes

I will test these out when so have access to my laptop.