I want to make my enemy chasing me when player in radius
but enemy is not able to catch player no matter how fast it is
I have tried many thing in can find on google but still not able to make it work
local pathfindingService = game:GetService("PathfindingService")
local players = game:GetService("Players")
local runtime = game:GetService("RunService")
local model = script.Parent
local humanoid = model.Humanoid
local observationDistance = 50
local normalSpeed = 10
local chasingSpeed = 60
local function CreatePath(destination)
local path = pathfindingService:CreatePath({
AgentRadius = 5,
AgentHeight = 9,
AgentCanJump = true
})
path:ComputeAsync(model.PrimaryPart.Position, destination)
print(path)
return path
end
local function NearbyPlayer()
local nearestPlayer
local minDistance = math.huge
for i, player in pairs(players:GetPlayers()) do
local character = player.Character or player.CharacterAdded:Wait()
local distance = (player.Character.PrimaryPart.Position - model.PrimaryPart.Position).Magnitude
if distance > observationDistance then continue end
if distance < minDistance then
minDistance = distance
nearestPlayer = player
end
end
return nearestPlayer
end
local function MoveTo(destination)
local player = NearbyPlayer()
if player == nil then
local path = CreatePath(destination)
humanoid.WalkSpeed = normalSpeed
if path and path.Status == Enum.PathStatus.Success then
local waypoints = path:GetWaypoints()
for _, waypoint in pairs(waypoints) do
player = NearbyPlayer()
if player ~= nil then return end
humanoid:MoveTo(waypoint.Position)
humanoid.MoveToFinished:Wait(2)
end
humanoid:MoveTo(destination)
end
else
local direction = (model.PrimaryPart.Position - player.Character.PrimaryPart.Position).Unit
humanoid.WalkSpeed = chasingSpeed
humanoid:Move(direction, false)
end
end
model.HumanoidRootPart:SetNetworkOwner(nil)
local function ChasingPlayer()
local player = NearbyPlayer()
if player == nil then
humanoid.WalkSpeed = normalSpeed
humanoid:Move(Vector3.new(0, 0, 0), false)
return
end
local direction = (player.Character.PrimaryPart.Position - model.PrimaryPart.Position).Unit
humanoid.WalkSpeed = chasingSpeed
humanoid:Move(direction, false)
end
local function Patrol()
local waypoints = workspace.Waypoints:GetChildren()
local randomInt = math.random(1, #waypoints)
local waypoint = waypoints[randomInt]
MoveTo(waypoint.Position)
end
while runtime.Heartbeat:Wait() do
--Patrol()
ChasingPlayer()
end
I think the problem is that the player’s character position changed since the character is moving which will, well, change the position of the character. You can make it so it detect if the player is moving or not, if then “break” the script since the player’s character position has changed.
I have made a ModuleScript that basically just pathfind the player’s character BUT there was one problem, no matter how far you are the character will always chase you.
This has to do with the server-client delay. There are a few things you can do to try and help this.
Make the enemy path find on the client
Make the enemy move in front of the player’s current moving direction & Make the enemy not collide with players, you’ll have to make use of CollisionGroups for this.
everytime the player moves the NPC has to create a new path and therefore it will stop before it can reach the player so what you can do is, when the NPC is within a certain distance from the player it will just move to the player instead of creating a new path to the player.
Test this you must repeat the compute path until he has founded a path
local pathfindingService = game:GetService("PathfindingService")
local players = game:GetService("Players")
local runtime = game:GetService("RunService")
local model = script.Parent
local humanoid = model.Humanoid
local observationDistance = 50
local path = pathfindingService:CreatePath({
AgentRadius = 5,
AgentHeight = 9,
AgentCanJump = true
})
local normalSpeed = 10
local chasingSpeed = 60
local function CreatePath(destination)
repeat path:ComputeAsync(model.PrimaryPart.Position, destination) until path.Status == Enum.PathStatus.Success
end
local function NearbyPlayer()
local nearestPlayer
local minDistance = math.huge
for i, player in pairs(players:GetPlayers()) do
local character = player.Character or player.CharacterAdded:Wait()
local distance = (player.Character.PrimaryPart.Position - model.PrimaryPart.Position).Magnitude
if distance > observationDistance then continue end
if distance < minDistance then
minDistance = distance
nearestPlayer = player
end
end
return nearestPlayer
end
local function MoveTo(destination)
local player = NearbyPlayer()
if player == nil then
CreatePath(destination)
humanoid.WalkSpeed = normalSpeed
local waypoints = path:GetWaypoints()
for _, waypoint in pairs(waypoints) do
player = NearbyPlayer()
if player ~= nil then return end
humanoid:MoveTo(waypoint.Position)
humanoid.MoveToFinished:Wait(1)
end
humanoid:MoveTo(destination)
else
local direction = (model.PrimaryPart.Position - player.Character.PrimaryPart.Position).Unit
humanoid.WalkSpeed = chasingSpeed
humanoid:Move(direction, false)
end
end
model.HumanoidRootPart:SetNetworkOwner(nil)
local function ChasingPlayer()
local player = NearbyPlayer()
if player == nil then
humanoid.WalkSpeed = normalSpeed
humanoid:Move(Vector3.new(0, 0, 0), false)
return
end
local direction = (player.Character.PrimaryPart.Position - model.PrimaryPart.Position).Unit
humanoid.WalkSpeed = chasingSpeed
humanoid:Move(direction, false)
end
local function Patrol()
local waypoints = workspace.Waypoints:GetChildren()
local randomInt = math.random(1, #waypoints)
local waypoint = waypoints[randomInt]
MoveTo(waypoint.Position)
end
while runtime.Heartbeat:Wait() do
--Patrol()
ChasingPlayer()
end
To OP: Set the network owner to the server and remove the move finished wait and make your own system for that. Then, use Humanoid:Move instead of MoveTo so it doesn’t stop.