Attack NPC only attacking when i am moving

Henlo frens, i have spent quite some time raising these NPCs to become good boys and attack the players when they are less than 2 studs away, however. They started to act naughty. While they do in fact attack the player. They only do so when the player is moving, so if the player stands still they just run into them akwardly. See below

here code fren

local collectionService = game:GetService("CollectionService")
local players = game:GetService("Players")
local runService = game:GetService("RunService")
local pathFindingService = game:GetService("PathfindingService")
local simplePath = require(game.ReplicatedStorage.SimplePath)

local raycastParams = RaycastParams.new()
raycastParams.FilterType = Enum.RaycastFilterType.Exclude
raycastParams.FilterDescendantsInstances = workspace.Map:GetChildren()

local maxDistance = 30

local function checkIfFov(funnyMan)
	local head = funnyMan.Head.CFrame.LookVector
	local vis = false

	for _, player in pairs(players:GetPlayers()) do
		
		local playerPos = player.Character:WaitForChild("HumanoidRootPart").Position
		local distanceFromNPC = (funnyMan.HumanoidRootPart.Position - playerPos).magnitude
		if distanceFromNPC <= 20 then
			local NPCToPlayer = (funnyMan.Head.Position - playerPos).Unit
			local dot = NPCToPlayer:Dot(head)

			if dot <= -0.5 then
				vis = true
				return player, distanceFromNPC
			else
				vis = false
			end
		end
	end
end


local function getClosestPlayer(funnyMan)
	local nearestPlayer, nearestDistance
	for _, player in pairs(players:GetPlayers()) do
		local character = player.Character
		if funnyMan:FindFirstChild("HumanoidRootPart") then
			local distance = player:DistanceFromCharacter(funnyMan.HumanoidRootPart.Position)
			if not character or 
				distance > maxDistance or
				(nearestDistance and distance >= nearestDistance)
			then
				continue
			end
			nearestDistance = distance
			nearestPlayer = player
		end
	end
	
	if nearestPlayer then
		return nearestPlayer
	end
end

local function checkIfCanSee(funnyMan, player)
	raycastParams.FilterDescendantsInstances = {funnyMan, player.Character}
	local rayDirection = player.Character.HumanoidRootPart.Position-funnyMan.HumanoidRootPart.Position
	local raycast = workspace:Raycast(funnyMan.HumanoidRootPart.Position, rayDirection)
	if raycast ~= nil then
		return raycast.Instance
	end
end

local function funnyFunc(funnyMan, nearestPlayer)
	if nearestPlayer then
		funnyMan.PrimaryPart.CFrame = CFrame.new(funnyMan.PrimaryPart.Position, Vector3.new(nearestPlayer.Character.PrimaryPart.Position.X, funnyMan.PrimaryPart.Position.Y, nearestPlayer.Character.PrimaryPart.Position.Z))
	end
end

local funnyMen = collectionService:GetTagged("Enemy")
function enemystuff(v)
	local humanoid = v:WaitForChild("Humanoid")
	local detectEvent = v:FindFirstChild("Detect")
	local animator = humanoid:WaitForChild("Animator")
	local idleAnim = Instance.new("Animation")
	idleAnim.AnimationId = "rbxassetid://14185521194"
	local idleAnimTrack = animator:LoadAnimation(idleAnim)

	local walkAnim = Instance.new("Animation")
	walkAnim.AnimationId = "rbxassetid://14506757573"
	local walkAnimTrack = animator:LoadAnimation(walkAnim)

	local atkAnim = Instance.new("Animation")
	atkAnim.AnimationId = "rbxassetid://14560685106"
	local atkAnimTrack = animator:LoadAnimation(atkAnim)


	task.defer(function()
		local detected = false
		local hurtDetect = false
		local pathfinding = false
		local attackDb = false
		local attacking = false

		idleAnimTrack:Play()

		runService.Heartbeat:Connect(function()
			local closestPlayer = getClosestPlayer(v)

			if closestPlayer then
				local fov, dist = checkIfFov(v)
			
				if fov ~= nil then
					local cansee = checkIfCanSee(v, fov)
					
					
					
					---THIS IS THE ATTACK PART
					if attackDb == false and dist <= 2 then
						print(dist)
						attackDb = true
						v.Attack:Play()
						atkAnimTrack:Play()
						closestPlayer.Character.Humanoid:TakeDamage(5)
						wait(0.5)
						attackDb = false
					else
						
						
						
					end
					if cansee:HasTag("wall") then
					else
						if pathfinding == false then
							pathfinding = true
							v.Scream:Play()
							idleAnimTrack:Stop()
							walkAnimTrack:Play()
							while pathfinding do
								if v ~= nil then
									local path = simplePath.new(v)
									path:Run(closestPlayer.Character.PrimaryPart.Position)
									if v.Humanoid.Health == 0 then
										path:Stop()
										walkAnimTrack:Stop()
									end
								end
							end
						end
					end
				end

				detectEvent.OnServerEvent:Connect(function(player)
					if detected == false then
						local cansee = checkIfCanSee(v, player)
						if cansee:HasTag("wall") then
						else
							funnyFunc(v, closestPlayer)
							detected = true
							wait(5)
							detected = false
						end
					end
				end)

				v:WaitForChild("Humanoid").HealthChanged:Connect(function()
					if hurtDetect == false then
						hurtDetect = true
						funnyFunc(v, closestPlayer)
						wait(5)
						hurtDetect = false
					end
					
					if v.Humanoid then
						if v.Humanoid.Health == 0 then
							wait(3)
							walkAnimTrack:Stop()
							v:Destroy()
						end
					end
				end)
			end
		end)
	end)
end

local funnyMen = collectionService:GetTagged("Enemy")

for i,v in funnyMen do
	if v:WaitForChild("Humanoid").Health ~= 0 then
		enemystuff(v)
	end
end

collectionService:GetInstanceAddedSignal("Enemy"):Connect(enemystuff)

hopefully someone can help, thanke

1 Like

Aha! I think I found the issue, you’re calculating the distance and FOV when a player moves. Try calculating them even when the player isn’t moving and let me know how that goes!

Well yes that is the problem. I dont know why my code is only calculating distance and FOV when a player moves. I might just rewrite the code to make this work

nevermind. rewrote the script. works now thank you anyway

1 Like

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