Scripting HelpersARCHIVE
A little piece of Roblox history. Preserved for everyone, one question at a time.Read about the archive →
COMMUNITY QUESTION

Enemy NPC not doing damage. Does this have something to do with debounce?

Hey there, I've been scripting for quite a while now, but this is one of the first times I'm asking a question.

In a nutshell, I have an enemy NPC (pathfinding is in another script), the goal is to have a gui with a sword pop up above his head and have it turn red when he begins an attack (here an onTouched function begins to check if the player is blocking the attack or not, so that he does damage), then have it turn green when he's no longer attacking.

This in itsself works fine except for the damage part. I've tried alot of things by now (I've highlighted some of the code I tried), but it just refuses to work. I've also added a BoolValue as debounce, perhaps the problem is in said BoolValue? I'm out of ideas by now. Any help would be greatly appreciated.

local damageWeapon = script.Parent.Parent.Damage -- .Value(!)
local canBeDisarmed = script.Parent.Parent.CanBeDisarmed
local bladeWeapon = script.Parent
local optionalTouchPartWeapon = script.Parent.Parent.Pole
local wielderHead = script.Parent.Parent.Parent.Head

local basicAttackAnim = script.Parent.Parent.Parent.Attack
local basicAttackAnimPlay = script.Parent.Parent.Parent.Humanoid:LoadAnimation(basicAttackAnim)
local attacking = false
--local touched = false
local canDamage = script.Parent.Parent.CanDamage

local function warnAttack()
	wielderHead.AttackUI.SwordIcon.Visible = true
	wielderHead.AttackUI.SwordIcon.ImageColor3 = Color3.fromRGB(255,0,0)
	wait(0.2)
end

local function basicAttack()
	--print(canDamage.Value)
	basicAttackAnimPlay:Play()
wait(basicAttackAnimPlay.Length)
	wielderHead.AttackUI.SwordIcon.ImageColor3 = Color3.fromRGB(0,255,0)
--	wait (math.randomseed(3,5))
	
optionalTouchPartWeapon.Touched:Connect(function(hit)
		if canDamage.Value == true then
		canDamage.Value = false
		--	print("attacking")
		--if touched == false then
		--touched = true
						
		if hit.Parent:FindFirstChild("Humanoid") then
		--	if attacking == false then
			--	attacking = true
				if hit.Parent.Humanoid.IsBlocking.Value == false then
					if hit.Parent.Humanoid.NPC.Value == false then
					hit.Parent.Humanoid:TakeDamage(damageWeapon.Value)
					bladeWeapon.HitSound:Play()
				wait(2)
				canDamage.Value = true
							-- if target is blocking		
					elseif hit.Parent.Humanoid.NPC.Value == false 
					and hit.Parent.Humanoid.IsBlocking.Value == true  then
				
					bladeWeapon.BlockSound:Play()
					bladeWeapon.Sparkles.Enabled = true
				wait(0.2)
					bladeWeapon.Sparkles.Enabled = false
						wielderHead.AttackUI.SwordIcon.ImageColor3 = Color3.fromRGB(0,255,0)
				wait(1)
						wielderHead.AttackUI.SwordIcon.Visible = false
								
					--elseif not hit.Parent:FindFirstChild("Humanoid") then
					--	canDamage.Value = true
						
					--else
					--canDamage.Value = true
				end
			end
		end
	end
end)
end

while wait(0.5) do
	if script.Parent.Parent.Parent.EnemyInSight.Value == true then
repeat
wait(2)
	warnAttack()
	basicAttack()
until  script.Parent.Parent.Parent.EnemyInSight.Value == false
		wielderHead.AttackUI.SwordIcon.Visible = false
	end
end

5 comments

0

look for any errors by writing /console

0

Hey there, thanks for the reply. I'm afraid the output doesn't give any errors as far as I've seen.

0

try make it print something after "if hit.Parent.Humanoid.NPC.Value = false then" and if it does print something then must be a error with how ur damaging him

0

I'm afraid it doesn't print anything. Really strange.

0

I think it's a problem with the debounce or the onTouched function as it doesn't print anything after "if hit.Parent.Humanoid.NPC.Value == false then"

2 answers

I pretty the problem is in the basicAttack function at line 41. The canDamage value only changes if hit.Parent.Humanoid.IsBlocking.Value == false and hit.Parent.Humanoid.NPC.Value == false. If the hit thing is blocking or is a npc then the rest of the code isn't allowed to be run which stops the canDamage from being set to true. So basically move the canDamage outside of the if statements as seen below.

local damageWeapon = script.Parent.Parent.Damage -- .Value(!)
local canBeDisarmed = script.Parent.Parent.CanBeDisarmed
local bladeWeapon = script.Parent
local optionalTouchPartWeapon = script.Parent.Parent.Pole
local wielderHead = script.Parent.Parent.Parent.Head

local basicAttackAnim = script.Parent.Parent.Parent.Attack
local basicAttackAnimPlay = script.Parent.Parent.Parent.Humanoid:LoadAnimation(basicAttackAnim)
local attacking = false
--local touched = false
local canDamage = script.Parent.Parent.CanDamage

local function warnAttack()
    wielderHead.AttackUI.SwordIcon.Visible = true
    wielderHead.AttackUI.SwordIcon.ImageColor3 = Color3.fromRGB(255,0,0)
    wait(0.2)
end

local function basicAttack()
    --print(canDamage.Value)
    basicAttackAnimPlay:Play()
wait(basicAttackAnimPlay.Length)
    wielderHead.AttackUI.SwordIcon.ImageColor3 = Color3.fromRGB(0,255,0)
--  wait (math.randomseed(3,5))

optionalTouchPartWeapon.Touched:Connect(function(hit)
        if canDamage.Value == true then
        canDamage.Value = false
        --  print("attacking")
        --if touched == false then
        --touched = true

        if hit.Parent:FindFirstChild("Humanoid") then
        --  if attacking == false then
            --  attacking = true
                if hit.Parent.Humanoid.IsBlocking.Value == false then
                    if hit.Parent.Humanoid.NPC.Value == false then 
                    hit.Parent.Humanoid:TakeDamage(damageWeapon.Value)
					bladeWeapon.HitSound:Play()
						
               		--{ wait(2) Take From Here
					--  canDamage.Value = true
					 -- if target is blocking     
						   
                    elseif hit.Parent.Humanoid.NPC.Value == false 
                    and hit.Parent.Humanoid.IsBlocking.Value == true  then

                    bladeWeapon.BlockSound:Play()
                    bladeWeapon.Sparkles.Enabled = true
                wait(0.2)
                    bladeWeapon.Sparkles.Enabled = false
                        wielderHead.AttackUI.SwordIcon.ImageColor3 = Color3.fromRGB(0,255,0)
                wait(1)
                        wielderHead.AttackUI.SwordIcon.Visible = false

                    --elseif not hit.Parent:FindFirstChild("Humanoid") then
                    --  canDamage.Value = true

                    --else
                    --canDamage.Value = true
                end
            end
        end
    end
	end)
	wait(2) --And Put here
    canDamage.Value = true
end

while wait(0.5) do
    if script.Parent.Parent.Parent.EnemyInSight.Value == true then
repeat
wait(2)
    warnAttack()
    basicAttack()
until  script.Parent.Parent.Parent.EnemyInSight.Value == false
        wielderHead.AttackUI.SwordIcon.Visible = false
    end
end

1 comment

0

Hey there! Thanks for the informative reply. Do pardon me for my late response, I was asleep when you posted this. I tried out your instructions and did as you said, but the script became very unreliable, it now does damage at seemingly random rather than doing damage when the attack is performed. I possibly (sort of) found a solution. I'll post it down here. Thanks again for your reply.

Alright, lassies and gents - I may have found the solution. I'm not sure what I did, but I'll post the script down below, only problem I currently have with it is that it doesn't register when the player is blocking. Thank you all for your replies (I'm very grateful for that), any more help would be greatly appreciated



local PathfindingService = game:GetService("PathfindingService")
math.randomseed(tick())

--local counter = 1

local enemySpotted = false
local CurrentPart = nil
local MaxInc = 16

local walkAnim = script.Parent.Walk
local walkAnimPlay = script.Parent.Humanoid:LoadAnimation(walkAnim)

local idleAnim = script.Parent.Idle
local idleAnimPlay = script.Parent.Humanoid:LoadAnimation(idleAnim)

local holdWeapon = script.Parent.HoldWeapon
local holdWeaponPlay = script.Parent.Humanoid:LoadAnimation(holdWeapon)

local followingPath = false

holdWeaponPlay:Play()



function findNearestTorso(pos)
	local list = game.Workspace:GetChildren()
	local torso = nil
	local dist = script.Parent.Distance.Value
	local temp = nil
	local human = nil
	local temp2 = nil
	for x = 1, #list do
		temp2 = list[x]
		if (temp2.className == "Model") and (temp2 ~= script.Parent) then
			temp = temp2:findFirstChild("RightUpperArm")
			human = temp2:findFirstChild("Humanoid")
			if (temp ~= nil) and (human ~= nil) and (human.Health > 0) and human["NPC"].Value == false then
				if (temp.Position - pos).magnitude < dist then
					torso = temp
					dist = (temp.Position - pos).magnitude
						
				end
			end
		end
	end
	return torso
end


local function chaseEnemy()
	while true do
		local target = findNearestTorso(script.Parent.UpperTorso.Position)
		wait(0.1)
		if target ~= nil then
		--	print("target found 1")
			--print(enemySpotted)
			enemySpotted = true
				script.Parent.EnemyInSight.Value = true
						
			local path = PathfindingService:CreatePath()
		path:ComputeAsync(script.Parent.HumanoidRootPart.Position, target.Position)
local waypoints = path:GetWaypoints()
			
script.Parent.Humanoid.Running:Connect(function(speed)
    if speed == 0 then
	print("I am standing")
--script.Parent.Humanoid:MoveTo(target.Position, target)
    end
			end)
			
for _, waypoint in pairs(waypoints) do ---
	
script.Parent.Humanoid:MoveTo(waypoint.Position)
	script.Parent.Humanoid.MoveToFinished:Wait()
				
		if waypoint.Action == Enum.PathWaypointAction.Jump then
       script.Parent.Humanoid:ChangeState(Enum.HumanoidStateType.Jumping)
    end
end	--script.Parent.Humanoid:MoveTo(target.Position, target)
			--print(enemySpotted)
		else
			--
			enemySpotted = false
			script.Parent.EnemyInSight.Value = false

repeat
		wait(1)
		script.Parent.Humanoid:MoveTo(script.Parent.UpperTorso.Position + Vector3.new(math.random(-MaxInc, MaxInc), 0, math.random(-MaxInc, MaxInc)), CurrentPart)
			idleAnimPlay:Stop()
			walkAnimPlay:Play()
		wait(3)
		walkAnimPlay:Stop()
		idleAnimPlay:Play()
		
		local target = findNearestTorso(script.Parent.UpperTorso.Position)
		if target ~= nil then
		--	print("target found 2")
					enemySpotted = true
						script.Parent.EnemyInSight.Value = true

		end
until enemySpotted == true	
		idleAnimPlay:Stop()
		walkAnimPlay:Play()	
		chaseEnemy()
end
	end
	end
local function repeatStuff()
	repeat
		wait(1)
		script.Parent.Humanoid:MoveTo(script.Parent.UpperTorso.Position + Vector3.new(math.random(-MaxInc, MaxInc), 0, math.random(-MaxInc, MaxInc)), CurrentPart)
			idleAnimPlay:Stop()
			walkAnimPlay:Play()
		--	script.Parent.Humanoid.MoveToFinished:Wait()
		wait(3)
			walkAnimPlay:Stop()
		idleAnimPlay:Play()
		
		local target = findNearestTorso(script.Parent.UpperTorso.Position)
		if target ~= nil then
			--print("target found 2")
			enemySpotted = true
			script.Parent.EnemyInSight.Value = true
		end
		
	until enemySpotted == true	
		idleAnimPlay:Stop()
		walkAnimPlay:Play()	
		chaseEnemy()
end

repeatStuff()

This discussion is preserved as it was. New answers, comments, and votes are closed.