So uh, i have some code that makes enemies wander around if there are no players, thing is, they’re meant to wander once every x seconds, but for some reason they just wander right after finishing a previous wander :^(
visual presentation (yes i am playing doom eternal with hdr shut up)
code that’s responsible for wandering;
local sScriptService = game:GetService("ServerScriptService")
local pfService = game:GetService("PathfindingService")
local dService = game:GetService("Debris")
-- Path to modules;
local enemies = sScriptService:WaitForChild("Enemies")
-- Modules;
local enemyStats = require(enemies.EnemyStats)
-- Path parameters!!
local pathParameters = {
AgentRadius = 2,
AgentHeight = 2,
AgentCanJump = true,
AgentCanClimb = false
}
function VisualizePath(waypoint: PathWaypoint)
local pathVisualizer = Instance.new("Part")
pathVisualizer.Shape = Enum.PartType.Ball
pathVisualizer.Parent = workspace
pathVisualizer.Position = waypoint.Position
pathVisualizer.Color = Color3.fromRGB(255,255,255)
pathVisualizer.Material = Enum.Material.Neon
pathVisualizer.Size = Vector3.new(2,2,2)
pathVisualizer.CanCollide = false
pathVisualizer.Anchored = true
dService:AddItem(pathVisualizer, 2)
end
function RandomWander(part: BasePart)
local minBound = part.Position - part.Size / 2
local maxBound = part.Position + part.Size / 2
-- Calculate bounds;
local minX = part.Position.X - part.Size.X / 2
local maxX = part.Position.X + part.Size.X / 2
local minZ = part.Position.Z - part.Size.Z / 2
local maxZ = part.Position.Z + part.Size.Z / 2
-- Randomize positions;
local randomX = math.random() * (maxX - minX) + minX
local randomZ = math.random() * (maxZ - minZ) + minZ
local fixedY = part.Position.Y
return Vector3.new(randomX, fixedY, randomZ)
end
-- Runtime;
local pathfinding = {}
function pathfinding.Wander(humanoid: Humanoid) -- Generates a random position and pathfinds to it (if player is not in LoS)
local char: Model = humanoid.Parent
local detectionPart: BasePart = char:FindFirstChild("DetectionPart")
local path: Path = pfService:CreatePath(pathParameters)
local humanoidRootPart: BasePart = char:FindFirstChild("HumanoidRootPart")
local startPos = humanoidRootPart.Position
local targetPos = RandomWander(detectionPart)
local success, result = pcall(function()
path:ComputeAsync(startPos, targetPos)
end)
if not success then
warn("Pathfinding failed: " .. result)
return
end
local waypoints = path:GetWaypoints()
if path.Status == Enum.PathStatus.Success and #waypoints > 0 then
humanoid.WalkSpeed = enemyStats[char.Name]["WANDER_SPEED"]
for i = 2, #waypoints do
local waypoint: PathWaypoint = waypoints[i]
if waypoint.Action == Enum.PathWaypointAction.Jump then
humanoid.Jump = true
end
VisualizePath(waypoint)
humanoid:MoveTo(waypoint.Position)
humanoid.MoveToFinished:Wait()
end
task.spawn(function()
local cooldown = math.random(5,10)
char:SetAttribute("WanderCooldown", true)
task.wait(cooldown)
char:SetAttribute("WanderCooldown", false)
end)
end
end
code that calls the wandering function
local pathfindingModule = require(game:GetService("ServerScriptService"):WaitForChild("Enemies").PathfindingModule)
local runService = game:GetService("RunService")
local enemiesFolder = workspace:WaitForChild("Enemies")
while task.wait(0.05) do
if #enemiesFolder:GetChildren() > 0 then
local enemies = enemiesFolder:GetChildren()
for _, enemy in ipairs(enemies) do
if enemy.EnemyType.Value == "MELEE" then
local detectionBox = enemy:FindFirstChild("DetectionPart")
local humanoid = enemy:FindFirstChildOfClass("Humanoid")
local closestPlayer = nil
local LOS = workspace:GetPartBoundsInBox(detectionBox.CFrame, detectionBox.Size)
for _, v in pairs(LOS) do
if v.Parent:FindFirstChild("Humanoid") then
local targetPlayer = game.Players:GetPlayerFromCharacter(v.Parent)
if targetPlayer then
if closestPlayer == nil or (enemy.HumanoidRootPart.Position - targetPlayer.Character.HumanoidRootPart.Position).Magnitude < (enemy.HumanoidRootPart.Position - closestPlayer.Character.HumanoidRootPart.Position).Magnitude then
closestPlayer = targetPlayer
end
end
end
end
task.spawn(function()
if closestPlayer then
local targetPosition = closestPlayer.Character.Torso.PathfindPart.Position
pathfindingModule.Chase(humanoid, targetPosition)
enemy:SetAttribute("Chasing", true)
else
if not enemy:GetAttribute("WanderCooldown") then
pathfindingModule.Wander(humanoid)
end
end
end)
end
end
end
end