EDIT: READ BOTTOM
This code works flawlessly in Play Solo. It bugs in Studio Test Server with 1 player, though. I have no idea why. I used to run it server-side and thought maybe I could fix it by running it client-side. Apparently not. This is the bottom-most part of the code. The top-part is only called in one function and that’s to draw a path.
while true do
for icount,vcount in pairs(Ignore:GetChildren()) do
if vcount:findFirstChild("Humanoid") and vcount.Humanoid.HealthDisplayDistance == 100 then
vcount.Humanoid.HealthDisplayDistance = 99
local CurrentTorso = vcount.Torso
local TargetTorso, MinDis = nil, 9999
for it,vt in pairs(Ignore.Players:GetChildren()) do
if vt:findFirstChild("Torso") then
local Mag = (CurrentTorso.Position-vt.Torso.Position).magnitude
if Mag < MinDis then
TargetTorso = vt.Torso
MinDis = Mag
end
end
end
--[[
local MinDis = MinDis+1
for it,vt in pairs(Ignore.Players:GetChildren()) do
if vt:findFirstChild("Torso") then
local Mag = (CurrentTorso.Position-vt.Torso.Position).magnitude
local Ray = RayN(CurrentTorso.Position, (vt.Torso.Position-CurrentTorso.Position).unit*Mag)
local Hit, Pos = workspace:FindPartOnRay(Ray, Ignore)
if Mag < MinDis and not Hit then
TargetTorso = vt.Torso
MinDis = Mag
end
end
end]]
local FinishPos, StartPos = TargetTorso.Position, CurrentTorso.Position
local StartMin, StartNode = 9999, nil
local FinishMin, FinishNode = 9999, nil
delay(0, function()
local Rayy = RayN(CurrentTorso.Position, (TargetTorso.Position-CurrentTorso.Position).unit*(CurrentTorso.Position-TargetTorso.Position).magnitude)
local Hit, Pos = workspace:FindPartOnRay(Rayy, Ignore)
if Hit then
for i,v in pairs(NodesList) do
for i,v in pairs(NodesList) do
local Rayy = RayN(v.Position, (StartPos-v.Position).unit*(StartPos-v.Position).magnitude)
local Hit, Pos = workspace:FindPartOnRay(Rayy, Ignore)
if not Hit then
if (v.Position-StartPos).magnitude < StartMin then
StartNode = v
StartMin = (v.Position-StartPos).magnitude
end
end
end
local Rayy = RayN(v.Position, (FinishPos-v.Position).unit*(FinishPos-v.Position).magnitude)
local Hit, Pos = workspace:FindPartOnRay(Rayy, Ignore)
if not Hit then
if (v.Position-FinishPos).magnitude < FinishMin then
FinishNode = v
FinishMin = (v.Position-FinishPos).magnitude
end
end
end
if StartNode and FinishNode then
local Result = Path(StartNode, FinishNode)
local Terminate = false
if Result[#Result].Node ~= StartNode then table.insert(Result, {Node = StartNode}) end
local TempRay = RayN(CurrentTorso.Position, (Result[#Result-1].Node.Position-CurrentTorso.Position).unit*(Result[#Result-1].Node.Position-CurrentTorso.Position).magnitude)
local TempHit, TempPos = workspace:FindPartOnRay(TempRay, Ignore)
if not TempHit then
table.remove(Result, #Result)
end
for i = 0, #Result-1 do
local Rayy = RayN(TargetTorso.Position, (FinishPos-TargetTorso.Position).unit*(FinishPos-TargetTorso.Position).magnitude)
local Hitt, Pos = workspace:FindPartOnRay(Rayy, Ignore)
if not Hitt and not Terminate then
local Target = Result[#Result-i].Node
repeat wait()
local TRayy = RayN(CurrentTorso.Position, (TargetTorso.Position-CurrentTorso.Position).unit*(TargetTorso.Position-CurrentTorso.Position).magnitude)
local THit, TPos = workspace:FindPartOnRay(TRayy, Ignore)
local Rayy = RayN(CurrentTorso.Position, (Target.Position-CurrentTorso.Position).unit*(Target.Position-CurrentTorso.Position).magnitude)
local HitT, Pos = workspace:FindPartOnRay(Rayy, Ignore)
if Result[#Result-i-1] then
local NextRayy = RayN(CurrentTorso.Position, (Result[#Result-i-1].Node.Position-CurrentTorso.Position).unit*(Result[#Result-i-1].Node.Position-CurrentTorso.Position).magnitude)
local NextHit, NextPos = workspace:FindPartOnRay(NextRayy, Ignore)
if not NextHit then NextHit = "Empty" end
else
NextHit = nil
end
local TPos = CFrame.new(CurrentTorso.Position, Target.Position)*CFrame.Angles(0,math.rad(math.random(-3,3)*8),0)*CFrame.new(0,0,-(CurrentTorso.Position-Target.Position).magnitude)
local Rel = CFrame.new(CurrentTorso.Position):inverse()*TPos
if HitT then Terminate = true end
game.ReplicatedStorage.Event:FireServer("Move", CurrentTorso.Parent.Name, Rel.p)
--CurrentTorso.Parent.Humanoid:Move(Rel.p, false)
CurrentTorso.Parent.Head.BrickColor = BrickColor.Random()
until Terminate or HitT or not THit or NextHit == "Empty" or (NextHit == nil and (CurrentTorso.Position-Target.Position).magnitude < 4)
end
end
end
else
--vcount.Name = "Direct path open"
--CurrentTorso.Parent.Humanoid:MoveTo(TargetTorso.Position, TargetTorso)
game.ReplicatedStorage.Event:FireServer("MoveTo", CurrentTorso.Parent.Name)
wait(0.2)
end
vcount.Humanoid.HealthDisplayDistance = 100
end)
end
end
wait(0.1)
end
So basically it’s looping through to find the closest player. Then it finds a path to him. This works in solo just fine (goes around walls and paths to the player) but in Studio Server testing it runs straight into walls. I’ve debugged in every position possible. All of the data given and received is exactly the same. It even draws the path and such… but it still refuses to walk through the path. Instead it hits a wall and keeps trying to walk into the player.
Edit: Sorry if it’s a little long. RayN = Ray.new for efficiency reasons… (not that I’m even close to finished optimizing)
EDIT: I found that :Move() on Humanoids isn’t cancelled when MoveTo() is run, same vice versa. They should cancel each other out when run to prevent further confusion like this. Apparently my code works fine