Hello, i’ve been working on an ai for a few days, and it worked well and never failed until I started building the map, and after that it was pretty much unusable and useless.
Here is a video showcasing the problem
As seen in the video, the ai sometimes idles, sometimes just walks off in a random direction, and takes a long while to do anything, it looks as though this is a pathfinding issue but roblox would’ve definitely patched such a critical issue by now, but yeah, sometimes the ai straight up stops working without an error message (removing the pcalls doesn’t give an error message aswell).
Here is a video of the ai stopping to work:
Sometimes they keep the walk animation, sometimes they don’t, it is all just confusing, and (edit: they always break when a player gets near it/them, not sometimes) they always break when a player gets near them (even though the script doesn’t mention the player or character at all), please help, i’ve already made several posts related to this particular ai as I was quite new to pathfinding when I started making it.
the posts (I don’t know if they will be relevant but extra info is always good! (I really hope)):
local ReplicatedStorage = game:GetService('ReplicatedStorage')
local Players = game:GetService('Players')
local CollectionService = game:GetService('CollectionService')
local PathfindingService = game:GetService('PathfindingService')
local RaycastHitbox = require(ReplicatedStorage.RaycastHitboxV4)
local MinerNumber = 0
CollectionService:AddTag(ReplicatedStorage.AI.Allies.Miner,'Miner')
CollectionService:GetInstanceAddedSignal('Miner'):Connect(function(Miner)
spawn(function()
Miner.Name = Miner.Name..tostring(MinerNumber)
MinerNumber += 1
local humrp = Miner.HumanoidRootPart
local hum = Miner.Humanoid
local WalkAnim = hum:LoadAnimation(script.Parent.Anims.walk.WalkAnim)
local MiningAnim = hum:LoadAnimation(script.Parent.Anims.Swing)
local PickUpAnim = hum:LoadAnimation(script.Parent.Anims.PickUp)
local oresPickedUp = {}
local Mining = false
local Params = RaycastParams.new()
Params.FilterDescendantsInstances = {Miner,workspace.OreSpawningArea} --- remember to define our character!
Params.FilterType = Enum.RaycastFilterType.Blacklist
local newHitbox = RaycastHitbox.new(Miner.Handle)
newHitbox:SetPoints(Miner.Handle,{Vector3.new(0,0,2)})
newHitbox.RaycastParams = Params
newHitbox.DetectionMode = RaycastHitbox.DetectionMode.PartMode
hum.Died:Connect(function()
game:GetService('Debris'):AddItem(Miner,5)
end)
local function getNearestOre()
local Ores = workspace.Ores:GetChildren()
local closestOre = nil
local closestDistance = nil
for _, Ore in pairs(Ores) do
local my_distance = (Ore.Main.Position - humrp.Position).Magnitude
if CollectionService:HasTag(Ore, "ToBeMined") then
continue
elseif closestOre == nil then -- nothing to compare add default
closestOre = Ore
closestDistance = my_distance
elseif Ore.Main and closestDistance > my_distance then -- default was set, time to compare
closestOre = Ore
closestDistance = my_distance
end
end
return closestOre
end
local function depositOres(walkToOre)
local path = PathfindingService:CreatePath()
local success, errorMessage = pcall(function()
path:ComputeAsync(humrp.Position, workspace.DepositOres.Position)
end)
WalkAnim:Play()
if success and path.Status == Enum.PathStatus.Success then
local waypoints = path:GetWaypoints()
for _,waypoint in pairs(waypoints) do
if waypoint.Action == Enum.PathWaypointAction.Jump then
hum:ChangeState(Enum.HumanoidStateType.Jumping)
end
hum:MoveTo(waypoint.Position)
hum.MoveToFinished:Wait()
end
for _,ore in pairs(oresPickedUp) do
require(ReplicatedStorage.FactoryResources).Resources[ore] += 1
end
oresPickedUp = {}
walkToOre()
else
task.wait(0.5)
depositOres()
end
end
local function pickUpOre(ores)
WalkAnim:Play()
for _,ore in pairs(ores) do
if ore and ore.Parent then
task.wait(0.1)
hum:MoveTo(ore.Position)
hum.MoveToFinished:Wait()
end
PickUpAnim:Play()
ore:Destroy()
table.insert(oresPickedUp,ore.Name)
end
WalkAnim:Stop()
return true
end
local function breakOre(nearest)
if Mining == false then
CollectionService:RemoveTag(nearest, "ToBeMined")
Mining = true
Miner:SetPrimaryPartCFrame(CFrame.new(humrp.Position,nearest.Main.Position))
MiningAnim:Play()
newHitbox:HitStart()
-- I apologize to my future self on my terrible readability on this code
newHitbox.OnHit:Connect(function(hit)
if hit:FindFirstAncestor('Ores') then
local oreName = hit.Parent.Name
local OreHealth = hit.Parent.Health.Value
if OreHealth >= 2 then
hit.Parent.Health.Value -= 1
Miner.Handle.Hit:Play()
local Particles = script.Smoke:Clone()
delay(0.3,function()
local newPart = Instance.new('Part')
newPart.Transparency = 1
newPart.Anchored = true
newPart.Position = Miner.Handle.Attachment.WorldPosition
newPart.Parent = Miner
Particles.Parent = newPart
delay(0.5,function()
Particles.Enabled = false
game:GetService('Debris'):AddItem(newPart,1)
end)
end)
else
Miner.Handle.Break:Play()
local ores = {}
for _,ore in pairs(hit.Parent:GetChildren()) do
if ore.Name == 'Ore' then
ore.Name = ore.Parent.Name
ore.Anchored = false
ore.Parent = workspace
table.insert(ores,ore)
ore.Touched:Connect(function(Hit)
if Players:GetPlayerFromCharacter(Hit.Parent) then
require(ReplicatedStorage.FactoryResources).Resources[oreName] += 1
ore:Destroy()
end
end)
end
end
if hit.Parent and hit.Parent.Name ~= 'Workspace' and hit.Parent:IsA('Model') then
hit.Parent:Destroy()
end
local allOresPickedUp = pickUpOre(ores)
while task.wait(1) do
if allOresPickedUp then
break
end
end
end
end
end)
task.wait(0.75)
newHitbox:HitStop()
Mining = false
end
end
local function walkToOre()
if #oresPickedUp < 4 then
local path = PathfindingService:CreatePath()
local nearest = getNearestOre()
if nearest == nil or nearest.Main == nil then
task.wait(0.5)
walkToOre()
return
end
CollectionService:AddTag(nearest, "ToBeMined")
local success, errorMessage = pcall(function()
path:ComputeAsync(humrp.Position, nearest.Main.Position + ((humrp.Position-nearest.Main.Position).Unit * 6))
end)
WalkAnim:Play()
if success and path.Status == Enum.PathStatus.Success then
local waypoints = path:GetWaypoints()
for _,waypoint in pairs(waypoints) do
if waypoint.Action == Enum.PathWaypointAction.Jump then
hum:ChangeState(Enum.HumanoidStateType.Jumping)
end
if nearest and nearest.Parent and (humrp.Position - nearest:GetPivot().Position).Magnitude <= 10 then
breakOre(nearest)
end
hum:MoveTo(waypoint.Position)
hum.MoveToFinished:Wait()
end
end
-- removes tag if failed to mine
if nearest and nearest.Parent then
CollectionService:RemoveTag(nearest, "ToBeMined")
end
WalkAnim:Stop()
task.wait(0.5)
walkToOre()
else
depositOres(walkToOre)
end
end
walkToOre()
end)
end)
local clone = ReplicatedStorage.AI.Allies.Miner:Clone()
clone.Parent = workspace.Allies
task.wait(0.3)
local clone = ReplicatedStorage.AI.Allies.Miner:Clone()
clone.Parent = workspace.Allies
clone:SetPrimaryPartCFrame(CFrame.new(Vector3.new(-150.777, 4, 50.515)))
task.wait(0.3)
local clone = ReplicatedStorage.AI.Allies.Miner:Clone()
clone.Parent = workspace.Allies
clone:SetPrimaryPartCFrame(CFrame.new(Vector3.new(-150.777, 4, 50.515)))
task.wait(0.3)
local clone = ReplicatedStorage.AI.Allies.Miner:Clone()
clone.Parent = workspace.Allies
clone:SetPrimaryPartCFrame(CFrame.new(Vector3.new(-150.777, 4, 50.515)))