[SOLVED] NPC Monster Attack Script 3

(Repost as the people who were talking to me just stopped talking.)
Attempt Number 3.
Can someone Please. help me? I’ve been at this for like 12 days now and nobody has replied back. I’ve done all I can and I don’t know what to do anymore. Please. Someone. Help me finally finish this script. I’ve been stuck on this for so long and it’s the only thing holding me back from continuing development on my game.

Ok so I’m trying to edit a script I’m using following a guide, but here are 2 problems.

  1. Even though I make the script not insta kill the player, it does it anyways and it only sometimes damages the player the correct amount (It’s this exact script because I tested if it was something else and it wasn’t)
  2. The attack animation does not play when the player is being attacked
    How do I fix this?
local teddy = script.Parent
local humanoid = teddy:WaitForChild("Humanoid")
local animation = script:WaitForChild('Attack')
local dance = humanoid:LoadAnimation(animation)
dance:Play()

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
		dance:Play()
		target.Humanoid.Health -= 40
		wait(2)
		attacked = false
	end
end

image

are those the only lines in your code? I’m trying to see as to when ‘teddy’ executes the attack function

as for the attack animation, do prints after everytime the animation plays, if it prints then the problem must lie in the priority of animation

Sorry I keep forgetting to add the whole script. I’ll send it to you

Here is the script.

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 function attack(target, teddyPart)
    local distance = (teddyPart.Position - getHumPos()).Magnitude
    if distance < 4 and game.Players:GetPlayerFromCharacter(target) then
        target.Humanoid.Health -= 40
        local plr = game.Players:GetPlayerFromCharacter(target)
        dance:Play()
        wait(2)
    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

A simple work around the kill script is making it so a part of the monster has a kill script inside it, so perhaps you could do if touch,check the humanoid, and then kill the charachter and play the animation

As for the animation, is it client sided or server sided? Had a few bugs happen to me

Touched really is not a great detection, you should probably use a hitbox module or magnitude, if you want to insta kill the humanoid just set the target humanoid health to 0, as for animations, make sure the animation is uploaded to your account or your group.

I belive the animation is server sided, but I’d like to make the monster only deal 40 damage so the player has 3 chances to get away from the monster.

I’m sorry but I do not know how to do that. I am only a beginner scripter. As for the instant kill, I’d like for the monster to only do 40 damage so the player has a chance to get away.

Which is why it would be beneficial to use a hitbox module.
I recommend Silly Cats hitbox module, using touch is unreliable and will yield attacks multiple times, or not even one attack. I recommend reading up on Modules as they are VERY useful for game dev and almost all games are comprised of mostly modules.

I belive there is a variable like Damage() to take a certain ammount of damage, i think i saw it somewhere, i am not 100% sure tho you can look it up

The attack is not accurate because the Touched event is triggered multiple times, to solve it a Debounce is required.
Also the function getHumPos() was not well defined, in my personal opinion of course.
After applying some patches your code is now working, at least the damage part.

As for the animation there are no problems in the code. You should check things like: if you own the animation, the animation plays in a Place you created (not in Studio) or things like that.

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

local function getHumPos(character: Model)
    return character:FindFirstChild("HumanoidRootPart") and character.HumanoidRootPart.Position
end

local debounce = false
local function attack(target: Model, teddyPart: BasePart)
    local distance = getHumPos(target) and (teddyPart.Position - getHumPos(target)).Magnitude
    if distance and distance < 4 and target:FindFirstChild("Humanoid") then
        if debounce then return end
        debounce = true
        target.Humanoid.Health -= 40
        --local plr = game.Players:GetPlayerFromCharacter(target)
        dance:Play()
        wait(2) -- the npc will attack only every 2 seconds
        debounce = false
    end
end

local function detection(part, teddyPart)
    if part.Parent and 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

--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)

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