[SOLVED] NPC Monster Attack Script 2

Ok so this post was a bit different before, but someone helped me with the original script.
After some playtesting, I found that the script does the attack animation, but it doesn’t give it time to finish the animation entirely and sometimes it just stops midway.
I was going over this with the original helper, but they’re currently busy with their work.
How can I add a cooldown for the attack?

-- declaring variables

local teddy = script.Parent
local humanoid = teddy.Humanoid
local animation = script:WaitForChild('Attack')
local dance = humanoid:LoadAnimation(animation)

local debounce = 0

-- special attack variables

local healthTakenFromAttack = 40

local atackCooldown = 0.8

local minDistance = 7

-- main code

local function attack(target)
	if target and target:FindFirstChild("Humanoid") and debounce == 0 then
		local distance = (teddy.HumanoidRootPart.Position - target.HumanoidRootPart.Position).Magnitude
		distance = distance / 1
		print(distance)
		if distance < minDistance and game.Players:GetPlayerFromCharacter(target) and target.Humanoid.Health > 0 then
			local AttackSound = {
				teddy.Head.Hit1,
				teddy.Head.Hit2,
				teddy.Head.Hit3
			}
			local chosen = AttackSound[math.random(1,#AttackSound)]
			debounce = 1
			chosen:Play()
			target.Humanoid.Health -= 40
			dance:Play()
			print("YES")
			wait(atackCooldown)
			local plr = game.Players:GetPlayerFromCharacter(target)
			debounce = 0

		end
	end
end

-- THIS LINE OF CODE IS NOT NEEDED.

--[[
teddy.HumanoidRootPart.Touched:Connect(function(hit)
	if hit.Parent and hit.Parent:FindFirstChild("Humanoid") then
		local character = hit.Parent
		if game.Players:GetPlayerFromCharacter(character) then
			local distance = (teddy.HumanoidRootPart.Position - character.HumanoidRootPart.Position).Magnitude
			if distance < 4 and character.Humanoid.Health > 0 then
				character.Humanoid.Health -= 0

				wait(2)
			end
		end
	end
end)
]]-- 

local function detection(part, teddyPart, hit)
	if part.Parent and part.Parent:FindFirstChild("Humanoid") then
		local character = part.Parent
		if game.Players:GetPlayerFromCharacter(character) then
			if character.Humanoid.Health > 0 and character ~= teddy then
				attack(character)
			end
		end
	end
end

for i,v in pairs(script.Parent:GetDescendants()) do
	if v:IsA("BasePart") or v:IsA("MeshPart") or v:IsA("UnionOperation") then
		if not string.find(v.Name, "cloth") then
			v.Touched:Connect(function(hit)
				detection(hit, v, hit)
			end)
		end
	end
end

I have a place file that has the monster already set up. If you want to playtest, then feel free to PM me and I’ll give you the file
image

Where is the attack function being used at?

1 Like

Ok hold on I’ll get the script, I’m just replying to let you know I’m here.

Here.

local teddy = script.Parent
local humanoid = teddy.Humanoid
local animation = script:WaitForChild('Attack')
local dance = humanoid:LoadAnimation(animation)

local function getHumPos()
	return (teddy.HumanoidRootPart.Position)
end

local attacked = false

local function attack(target, teddyPart)
	local distance = (teddyPart.Position - getHumPos()).Magnitude
	if distance < 4 and game.Players:GetPlayerFromCharacter(target) and attacked == false then
		attacked = true
		target.Humanoid.Health -= 40
		local plr = game.Players:GetPlayerFromCharacter(target)
		dance:Play()
		wait(2)
		attacked = false
	end
end

script.Parent.Reached.Event:Connect(function(target)
	if target.Character then
		if target.Character.Humanoid.Health > 0 then
			target.Character.Humanoid.Health -= 40
			dance:Play()
			wait(2)
		end
	end
end)
local function detection(part, teddyPart)
	if part.Parent:FindFirstChild("Humanoid") then
		local character = part.Parent
		if game.Players:GetPlayerFromCharacter(character) then
			--Check the player is still alive (And it's not our own character)
			if character.Humanoid.Health > 0 and character ~= teddy then
				attack(character, teddyPart)
			end
		end
	end
end

for i,v in pairs(script.Parent:GetDescendants()) do
	if v:IsA("BasePart") or v:IsA("MeshPart") or v:IsA("UnionOperation") then
		if not string.find(v.Name, "cloth") then
			v.Touched:Connect(function(hit)
				detection(hit, v)
			end)
		end
	end
end

Hello again @FentTamer sorry for the reply but I am just checking if you are still interested in helping me fix my script. The last time I was waiting for someone they didn’t reply until the next morning or just stopped replying entirely

Does the player take damage?

Have you tried loading the animation through the Animator of the Humanoid, instead of directly on the humanoid?

Yes. The player is supposed to take 40 damage but it’s supposed to have a cooldown but it gets spammed so the player instantly dies.
How would I load the animation through the Animator?

while true do
for i, v in pairs(game.Workspace:GetChildren()) do
if v:IsA(‘Model’) and v ~= teddy then
local teddyPart = v:FindFirstChild(‘Head’) or v:FindFirstChild(‘HumanoidRootPart’) or v:FindFirstChild(‘Torso’)
if teddyPart then
attack(v, teddyPart)
end
end
end
wait(1)
end

Your script isn’t working because animation:Play() is not a valid function; you should use humanoid:LoadAnimation(animation):Play() instead.

Where would I put this script?

while true do
   for i, v in pairs(game.Workspace:GetChildren()) do
      if v:IsA(‘Model’) and v ~= teddy then
         local teddyPart = v:FindFirstChild(‘Head’) or v:FindFirstChild(‘HumanoidRootPart’) or 
         v:FindFirstChild(‘Torso’)
         if teddyPart then
            attack(v, teddyPart)
         end
      end
   end
   wait(1)
end

Is this a custom rig? I have experience with custom rigs with their AI’s and playing animations on them.

Sorry for late reply, I had to do something and I completely forgot about it ;-;
Anyways.
No, this is not a custom rig, and also someone already helped me with the monster AI. I just need to find a way to make the cooldown long enough so the animation fully plays and the player can get away in time.

its probably something to do with v.touched firing multiple times at the same time. maybe have a debounce at the .touched event instead?

you also have to understand, you seem to go throughout the the script.parent descendants so its also possible that other parts are also activating hit simultaneously

Sorry I’m going to edit the post. Someone already solved the issue, now I just need to figure out how to make the animation have time to finish entirely.

You can do

dance.Completed:Wait()

And pause the loop while the animation is playing

2 Likes

Oh my gosh thank you this works, I just had to change it to

dance.Ended:wait()

My mistake, I accidentally gave you the wrong event :sweat_smile:, but I’m glad it works now.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.