Hi, I am currently re-working on my game and I am struggling with pathfinding for enemies. For some reason, those dummies won’t create waypoints if there are height differences between them and the player (e.g., they are on a 2-stud height part; they could just let themselves fall but they don’t want to).
Here is the script, please help:
local PathfindingService = game:GetService(“PathfindingService”)
local NPC = script.Parent.Parent
local coreFold = NPC.CoreFolder
local humanoid = NPC:WaitForChild(“Humanoid”)
local humRP = NPC:WaitForChild(“HumanoidRootPart”)
local MAX_RETRIES = 5
local RETRY_COOLDOWN = .001
local path = PathfindingService:CreatePath()
local reachedConnection
local CombatState = false
local CombatStateDistance = 20
local randomWalkDuration = 1 – Durée en secondes de la marche aléatoire
local maxRandomWalkDistance = 40 – Distance maximale à parcourir pendant la marche aléatoire
– Fonction pour obtenir la cible Humanoid la plus proche
local function getClosestHumanoid()
local closestHumanoid
local closestDistance = 150
-- Parcourez tous les objets dans l'environnement
for _, entity in ipairs(workspace:GetChildren()) do
-- Vérifiez s'il s'agit d'un Humanoid et s'il n'est pas le parent lui-même
if entity:IsA("Model") and entity:FindFirstChild("Humanoid") and entity:FindFirstChild("Humanoid").Health > 0 and entity ~= NPC then
local function ClosingUp()
local distance = (entity:FindFirstChild("HumanoidRootPart").Position - humRP.Position).Magnitude
if distance < closestDistance then
closestHumanoid = entity:FindFirstChild("Humanoid")
closestDistance = distance
if distance < CombatStateDistance then
CombatState = true
else
CombatState = false
end
end
end
if entity:FindFirstChild("Team") then
if entity.Team.Value ~= NPC.Team.Value then
ClosingUp()
end
else
ClosingUp()
end
end
end
return closestHumanoid
end
local function walkTo(targetPosition, yieldable)
local RETRY_NUM = 0
local success, errorMessage
repeat
RETRY_NUM += 1 -- ajoutez un essai
success, errorMessage = pcall(path.ComputeAsync, path, humRP.Position, targetPosition)
if not success then -- si cela échoue, avertissez le message
warn("Pathfind compute path error: "..errorMessage)
task.wait(RETRY_COOLDOWN)
end
until success == true or RETRY_NUM > MAX_RETRIES
if success then -- si le calcul du chemin ne pose pas de problème
if path.Status == Enum.PathStatus.Success then
local waypoints = path:GetWaypoints()
local currentWaypointIndex = 2 -- pas 1, car 1 est le waypoint de la position de départ.
if waypoints[currentWaypointIndex].Position.Y > humRP.Position.Y + humanoid.HipHeight then
-- Il y a un obstacle en hauteur, le NPC doit sauter ou se laisser tomber
humanoid:Move(Vector3.new(0, waypoints[currentWaypointIndex].Position.Y - humRP.Position.Y, 0))
else
humanoid:MoveTo(waypoints[currentWaypointIndex].Position) -- déplacez-vous vers le nième waypoint
end
if waypoints[currentWaypointIndex].Action == Enum.PathWaypointAction.Jump then
humanoid.Jump = true -- si cela nécessite un saut
end
else -- si le chemin ne peut pas être calculé entre deux points, ne faites rien !
return
end
else -- si la chance de réessayer est maximale
warn("Pathfind compute retry maxed out, error: "..errorMessage)
return
end
end
local function updateRotationToTarget(targetPosition)
local lookAtPosition = Vector3.new(targetPosition.X, humRP.Position.Y, targetPosition.Z) – Assurez-vous de garder la même hauteur (axe Y)
local newRotation = CFrame.new(humRP.Position, lookAtPosition)
NPC:SetPrimaryPartCFrame(newRotation) – Mettez à jour la rotation pour regarder la cible
end
local function performRandomWalk(targetPosition)
local randomWalkDirection = Vector3.new(math.random(-1, 1), 0, math.random(-1, 1)).unit
local randomWalkDistance = math.random(0, maxRandomWalkDistance)
local randomWalkStartPosition = humRP.Position
local randomWalkEndTime = tick() + randomWalkDuration
while tick() < randomWalkEndTime do
local currentWalkPosition = randomWalkStartPosition + randomWalkDirection * randomWalkDistance * (tick() - randomWalkEndTime + randomWalkDuration) / randomWalkDuration
updateRotationToTarget(targetPosition) -- Mettez à jour la rotation pour regarder la cible
walkTo(currentWalkPosition, true)
wait() -- Attendez un peu entre chaque mise à jour de la position
end
end
spawn(function()
while wait() do
local targetHumanoid = getClosestHumanoid()
if targetHumanoid then
local targetPosition = targetHumanoid.Parent:FindFirstChild(“HumanoidRootPart”).Position
if CombatState then
local randomFactor = math.random(0, 10)
if randomFactor <= 1 then
performRandomWalk(targetPosition)
else
walkTo(targetPosition, true)
end
else
updateRotationToTarget(targetPosition) -- Mettez à jour la rotation pour regarder la cible
walkTo(targetPosition, true)
end
end
end
end)