I have a combat system in which if an enemy or the player is hit for enough damage, they’ll flinch, cancelling their attack function if there is one currently going. It works perfectly fine for the player, but the same doesn’t go for the enemy npcs.
For enemies, the flinching stuff doesn’t happen until the attack stuff is finished. Flinch is meant to override/completely stop attacks, and yet, it doesn’t.
What I’ve tried so far that hasn’t worked is:
*Creating and yielding a coroutine
*Returning the attack function with an if statement (checking the if statement for every event during the attack)
*Doing the flinch stuff in a separate script which disables the main script with the attack stuff when flinching happens
Simplified version of relevant code:
{Humanoid:LoadAnimation(enemy:WaitForChild("AttackAnim")),function(anim) --attacking stuff
anim:GetMarkerReachedSignal("MoveStart"):Connect(function()
if BodyPositionCooldown == false then
BodyPositionCooldown = true
makeBodyPosition()
end
end)
anim:GetMarkerReachedSignal("HitStart"):Connect(function()
canDetect = true --Touch detection for damage when attacking
damage = x
hitbox.Touched:Connect(function(partHit)
if not canDetect then return end
local humanoid = partHit.Parent:FindFirstChild("Humanoid")
if humanoid then
canDetect = false
damage(humanoid)
else
end
end)
end)
anim:GetMarkerReachedSignal("HitEnd"):Connect(function()
canDetect = false
end)
anim.Stopped:Connect(function()
BodyPosition:Destroy()
BodyPositionCoolDown = false
end)
end}, --more in full table
function attack(target)
if attackCooldown then
attackCooldown = false
local attackAnim = x
AttackAnimations[attackAnim][3](AttackAnimations[attackAnim][1])
AttackAnimations[attackAnim][1]:Play()
Humanoid.WalkSpeed = 0
AttackAnimations[attackAnim][1].Stopped:Wait()
Humanoid.WalkSpeed = originalSpeed
local _ = target.Parent.Humanoid.Health < 1 and wait(0.1)
delay(1,function() attackCooldown = true end)
end
end
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
local function stopAnims()
local RunningTracks = Humanoid:GetPlayingAnimationTracks()
for _, v in pairs(RunningTracks) do
v:Stop()
end
end
while wait(0.05) do
if myHuman:GetState() == Enum.HumanoidStateType.Dead then break end
if PreviousHealth > Humanoid.Health and FlinchCooldown == false then --flinching stuff
if Humanoid.Health <= 0 then --Doesn't go off if NPC died
else
local Anim = Instance.new('Animation', HumanoidRootPart)
Anim.Name = "Flinching"
if PreviousHealth > Humanoid.Health then
FlinchCooldown = true
Anim.AnimationId = 'rbxassetid://6816963198'
local AnimationTrack = Humanoid:LoadAnimation(Anim)
canDetect = false
stopAnims()
Humanoid.WalkSpeed = 0
local bp = enemy:FindFirstChild("BodyPosition")
if bp then
bp:Destroy()
end
AnimationTrack:Play()
AnimationTrack.Stopped:wait()
Humanoid.WalkSpeed = originalSpeed
Anim:Destroy()
PreviousHealth = Humanoid.Health
FlinchCooldown = false
end
end
end
main()
end