I have a prolem of my NPC’s not attacking sometimes.
The NPC’s are supposed to attack when they play an animation.
Video:
ServerScript:
local character = script.Parent
local currentTarget = nil
local npcs = workspace:WaitForChild("Npcs") -- folder
local range = 100
local ProjectileTime = 1
local canShoot = true
local function castRay(target)
if target.PrimaryPart ~= nil then
local raycastParams = RaycastParams.new()
raycastParams.FilterDescendantsInstances = {npcs}
raycastParams.FilterType = Enum.RaycastFilterType.Whitelist
raycastParams.IgnoreWater = true
local rayOrigin = character.PrimaryPart.Position
local rayDestination = target.PrimaryPart.Position
local rayDirection = (rayDestination - rayOrigin)
local raycastResult = workspace:Raycast(rayOrigin, rayDirection, raycastParams)
if raycastResult then
local distance = math.floor(raycastResult.Distance)
if distance <= range then
currentTarget = target
return true, raycastResult.Position, distance
else
currentTarget = nil
return false, nil, nil
end
else
currentTarget = nil
end
else
currentTarget = nil
end
end
local function PredictNextPosition(targetPosition, targetVelocity)
if targetPosition ~= nil and targetVelocity ~= nil then
local t = ProjectileTime
local endPosition = targetPosition + targetVelocity * t
return endPosition
end
end
local function findTarget()
local checkRay, position, distance = nil, nil, nil
for i,v in ipairs(npcs:GetChildren()) do
if currentTarget == nil then
checkRay, position, distance = castRay(v)
else
checkRay, position, distance = castRay(currentTarget)
end
if currentTarget ~= nil then
local savedTarget = currentTarget
local targetRoot = currentTarget.PrimaryPart
local human = currentTarget:FindFirstChildWhichIsA("Humanoid")
if human and human.Health <= 0 then
currentTarget = nil
end
if distance ~= nil and distance > range then
currentTarget = nil
end
if player and human and human.Health > 0 and currentTarget ~= nil and targetRoot ~= nil then
local success, bool = pcall(function()
return Remotes.CheckOnScreen:InvokeClient(player, targetRoot, {npcs})
end)
if success and bool == true then
local characterRoot = character.PrimaryPart
character:PivotTo(CFrame.lookAt(characterRoot.Position, position * Vector3.new(1, 0, 1) + position * Vector3.new(0, 1, 0)))
if checkRay ~= nil and checkRay == true then
if tick() - currentTime >= damageCooldown then
currentTime = tick()
playAnimation()
checkRay, position, distance = castRay(savedTarget)
local nextPosition = PredictNextPosition(position, targetRoot.AssemblyLinearVelocity)
if checkRay ~= nil and checkRay == true and nextPosition ~= nil and canShoot == true and human and human.Health > 0 then
print("shoot")
end
end
end
end
end
end
end
end
RunService.Heartbeat:Connect(function()
if character.PrimaryPart ~= nil and canAttack.Value == true then
findTarget()
end
end)