I am currently making a Backrooms game, and I’m working on an entity called the “Hound”, and it chases the player unless they keep eye contact with it. But besides the point, I’m currently working on a system where they chase the closest player, but I am having some trouble with it. I’m not sure how I can find the closest player and then move the entity to that player, here is a script I’ve tried but doesn’t work at all.
--Services--
local RunService = game:GetService('RunService')
local PathfindingService = game:GetService('PathfindingService')
--Variable--
local hum = script.Parent.Humanoid
local humrp = script.Parent.HumanoidRootPart
local Animator = hum.Animator
--Pathfinding
local playerDistances = {}
local destination = workspace.Part.Position
local path = PathfindingService:CreatePath()
path:ComputeAsync(humrp.Position, destination)
local waypoints = path:GetWaypoints()
local function findPlayerDistances()
local RefreshDistances = coroutine.wrap(function()
while wait() do
for i,v in pairs(game.Players:GetPlayers()) do
local char = v.Character or v.CharacterAdded:Wait()
table.insert(playerDistances,{(char.HumanoidRootPart.Position - humrp.Position).Magnitude, char.HumanoidRootPart.Position})
end
table.clear(playerDistances)
end
end)
RefreshDistances()
end
findPlayerDistances()
local pathfindingService = game:GetService("PathfindingService")
local tweenService = game:GetService("TweenService")
local character = script.Parent
local humanoid = character:WaitForChild("Monster")
local chase_magnitude = character.Configuration.NoticeDistance.Value
local run_speed = character.Configuration.RunSpeed.Value
local walk_speed = character.Configuration.WalkSpeed.Value
local chasing = false
local dead = false
local originalC1 = character.Head.Neck.C1
local http = game:GetService('HttpService')
for index, part in pairs(character:GetDescendants()) do
if part:IsA("BasePart") then
part:SetNetworkOwner(nil)
end
end
function getNearestTarget()
local nearest_magnitude = math.huge
local nearest_character = nil
for index, player in pairs(game.Players:GetPlayers()) do
if player.Character then
if player.Character.Humanoid.Health > 0 then
if (player.Character.HumanoidRootPart.Position - character.HumanoidRootPart.Position).magnitude <= character.Configuration.NoticeDistance.Value then
if nearest_magnitude >= (player.Character.HumanoidRootPart.Position - character.HumanoidRootPart.Position).magnitude then
nearest_magnitude = (player.Character.HumanoidRootPart.Position - character.HumanoidRootPart.Position).magnitude
nearest_character = player.Character
end
end
end
end
end
return nearest_character
end
function getNearestTargetToSniff()
local nearest_magnitude = math.huge
local nearest_character = nil
for index, player in pairs(game.Players:GetPlayers()) do
if player.Character then
if player.Character.Humanoid.Health > 0 then
--if (player.Character.HumanoidRootPart.Position - character.HumanoidRootPart.Position).magnitude <= character.Configuration.NoticeDistance.Value then
if nearest_magnitude >= (player.Character.HumanoidRootPart.Position - character.HumanoidRootPart.Position).magnitude then
nearest_magnitude = (player.Character.HumanoidRootPart.Position - character.HumanoidRootPart.Position).magnitude
nearest_character = player.Character
end
--end
end
end
end
return nearest_character
end
function getTouchingParts(part)
local connection = part.Touched:connect(function() end)
local results = part:GetTouchingParts()
connection:Disconnect()
return results
end
while true do
game:GetService("RunService").Heartbeat:wait()
local target = getNearestTarget()
if target then
character.Chasing.Value = true
if not chasing then
chasing = true
else
humanoid.WalkSpeed = character.Configuration.RunSpeed.Value
end
local origin, direction = character.HumanoidRootPart.Position, (target.HumanoidRootPart.Position - character.HumanoidRootPart.Position).unit * 500
local ray = Ray.new(origin, direction)
local hit = workspace:FindPartOnRay(ray, character)
local pathFind = false
if hit then
if not hit:IsDescendantOf(target) then
pathFind = true
end
end
if pathFind then
if character:FindFirstChild("HumanoidRootPart") then
local path = pathfindingService:CreatePath()
path:ComputeAsync(character.HumanoidRootPart.Position, target.HumanoidRootPart.Position)
local waypoints = path:GetWaypoints()
for index, waypoint in pairs(waypoints) do
if waypoint.Action == Enum.PathWaypointAction.Jump then
humanoid.Jump = true
end
local origin, direction = character.HumanoidRootPart.Position, (target.HumanoidRootPart.Position - character.HumanoidRootPart.Position).unit * 500
local ray = Ray.new(origin, direction)
local hit = workspace:FindPartOnRay(ray, character)
local pathFind = false
if hit then
if not hit:IsDescendantOf(target) then
pathFind = true
end
end
if not pathFind then
break
end
humanoid:MoveTo(waypoint.Position)
humanoid.MoveToFinished:wait()
end
end
else
humanoid:MoveTo(target.HumanoidRootPart.Position)
if (character.HumanoidRootPart.Position - target.HumanoidRootPart.Position).magnitude <= 7 then
task.wait(.1)
wait(0.25)
humanoid.WalkSpeed = character.Configuration.RunSpeed.Value
end
end
else
character.Chasing.Value = false
local chance = math.random(1, 3)
humanoid.WalkSpeed = character.Configuration.WalkSpeed.Value
chasing = false
local seconds = 0
if chance == 1 then
if getNearestTargetToSniff() then
humanoid:MoveTo(getNearestTargetToSniff().HumanoidRootPart.Position)
seconds = 2
end
else
humanoid:MoveTo(Vector3.new(math.random(-330, -67), 0, math.random(-326, 339)))
seconds = math.random(3, 4)
end
for i = seconds/(1/60),1,-1 do
game:GetService('RunService').Heartbeat:wait()
if getNearestTarget() then
break
end
end
end
end
I have gotten it working, here is the new script for any people in the future that need it!
--Services--
local RunService = game:GetService('RunService')
local PathfindingService = game:GetService('PathfindingService')
--Variable--
local hum = script.Parent.Humanoid
local humrp = script.Parent.HumanoidRootPart
local Animator = hum.Animator
--Pathfinding
script.Parent.PrimaryPart:SetNetworkOwner(nil)
local destination = workspace.Part.Position
local function findTarget()
local players = game.Players:GetPlayers()
local MaxDistance = 200
local nearestTarget
for i,v in pairs(players) do
if (v.Character) then
local target = v.Character
local distance = (humrp.Position - target.HumanoidRootPart.Position).Magnitude
if (distance < MaxDistance) then
nearestTarget = target
MaxDistance = distance
end
end
end
return nearestTarget
end
local function agro(target)
local distance = (humrp.Position - target.HumanoidRootPart.Position).Magnitude
if (distance > 8) then
hum:MoveTo(target.HumanoidRootPart.Position)
else
target.Humanoid.Health = 0
end
end
local function createPath(destination)
local path = PathfindingService:CreatePath()
path:ComputeAsync(humrp.Position, destination)
return path
end
local function walkTo(destination)
local path = createPath(destination)
local waypoints = path:GetWaypoints()
for i,v in pairs(waypoints) do
local target = findTarget()
if (target) then
agro(target)
break
end
hum:MoveTo(v.Position)
hum.MoveToFinished:Wait()
end
end
while task.wait(0.5) do
walkTo(destination)
end
Hello! I know I am a bit late to this, but I was wondering what the purpose of local destination = workspace.Part.Position? I would like to understand this script more and know if I matters how I use the workspace part. Also my pathfinding character just walks into walls, anyway I could make him walk around (isn’t that the purpose of pathfinding?)