local humanoidrootpartpos = {}
function getHumanoid(model)
for _, h in pairs(model:GetChildren()) do
if h:IsA("Humanoid") then
return h
end
end
end
local ai = script.Parent
local human = getHumanoid(ai)
local hroot = ai.HumanoidRootPart
local hspeed = hroot.Velocity.magnitude
local pfs = game:GetService("PathfindingService")
function GetPlayerNames()
local players = game:GetService("Players"):GetChildren()
local name = nil
for _, p in pairs(players) do
if p:IsA("Player") then
name = tostring(p.Name)
end
end
return name
end
function GetPlayersBodyParts(t)
local torso = t
if torso then
local figure = torso.Parent
for _, v in pairs(figure:GetChildren()) do
if v:IsA("Part") then
return v.Name
end
end
else
return ("HumanoidRootPart")
end
end
function GetTorso(part)
local chars = game.Workspace:GetChildren()
local torso = nil
for _, c in pairs(chars) do
if c:IsA("Model") and c ~= script.Parent and c.Name == GetPlayerNames() then
local charRoot = c:FindFirstChild("HumanoidRootPart")
local mag = (charRoot.Position - part).magnitude
table.insert(humanoidrootpartpos,mag)
print(humanoidrootpartpos[1])
torso = charRoot
end
end
return torso
end
for _, aiparts in pairs(ai:GetChildren()) do
if aiparts:IsA("Part") then
aiparts.Touched:Connect(function(p)
if p.Parent.Name == GetPlayerNames() and p.Parent.Name ~= ai.Name then
local enemy = p.Parent
local ehuman = getHumanoid(enemy)
ehuman.Health = 0
end
end)
end
end
local path
local waypoint
local oldpoints
local isWandering = 0
while wait() do
local TargetMag = math.min(unpack(humanoidrootpartpos))
local enemytorso = GetTorso(hroot.Position)
if enemytorso ~= nil then -- if player detected
if (enemytorso.Position - hroot.Position).magnitude == TargetMag then
isWandering = 1
local function checkw(t)
local ci = 3
if ci > #t then
ci = 3
end
if t[ci] == nil and ci < #t then
repeat
ci = ci + 1
wait()
until t[ci] ~= nil
return Vector3.new(1, 0, 0) + t[ci]
else
ci = 3
return t[ci]
end
end
path = pfs:FindPathAsync(hroot.Position, enemytorso.Position)
waypoint = path:GetWaypoints()
oldpoints = waypoint
local connection;
local direct = Vector3.FromNormalId(Enum.NormalId.Front)
local ncf = hroot.CFrame * CFrame.new(direct)
direct = ncf.p.unit
local rootr = Ray.new(hroot.Position, direct)
local phit, ppos = game.Workspace:FindPartOnRay(rootr, hroot)
if path and waypoint or checkw(waypoint) then
if checkw(waypoint) ~= nil and checkw(waypoint).Action == Enum.PathWaypointAction.Walk then
human:MoveTo( checkw(waypoint).Position )
human.Jump = false
end
if connection then
connection:Disconnect()
end
else
for i = 3, #oldpoints do
human:MoveTo( oldpoints[i].Position )
end
end
end
end
end
I made a script for this ai detecting the closest player and make it move to it
it doesnt find the smallest magnitude and just errors when I use math.min
here’s the line that is errored and the output:
Line:
local TargetMag = math.min(unpack(humanoidrootpartpos))
Output: bad argument #1 (number expected, got no value)
OK, here’s a code that does basically the same as your functions, but much faster and more compact.
local serPlayers = game:GetService("Players")
local GetClosestPlayerTo = function(pos0)
local closestplyr
local closestpos
local closestmag = math.huge
for _,plyr in pairs(serPlayers:GetPlayers())
local char = plyr.Character
if char then
local hrp = char.HumanoidRootPart
local pos1 = hrp.Position
local mag = (pos1-pos0).magnitude
if closestmag>mag then
closestplyr = plyr
closestmag = mag
closestpos = pos1
end
end
end
return closestplyr,closestpos
end
I can see a lot of issues here which make it very hard to debug, so I am going to point out the most obvious ones.
In getHumanoid, you could easily replace this all with return model:FindFirstChild(“Humanoid”) since humanoids are always called Humanoid.
In GetPlayerNames, p:IsA(“Player”) is not needed as all children of Players are players. tostring(p.Name) is also obsolete as the name is already a string. This function also doesn’t make much sense as the name implies you are getting multiple names, while you are actually getting the name of a single player at random.
GetPlayersBodyParts doesn’t make any sense.
As said in my deleted post, you are iterating over all children of workspace instead of checking in the players that have characters. This was addressed in my code.
I don’t know if this works, plus I typed this out in Notepad++ so tabs are replaced with 4 spaces, but here it is.
local serPlayers = game:GetService("Players")
local ai = script.Parent
local human = getHumanoid(ai)
local hroot = ai.HumanoidRootPart
local hspeed = hroot.Velocity.magnitude
local pfs = game:GetService("PathfindingService")
local GetClosestPlayerTo = function(pos0)
local closestplyr
local closestpos
local closestmag = math.huge
for _,plyr in pairs(serPlayers:GetPlayers())
local char = plyr.Character
if char then
local hrp = char.HumanoidRootPart
local pos1 = hrp.Position
local mag = (pos1-pos0).magnitude
if closestmag>mag then
closestplyr = plyr
closestmag = mag
closestpos = pos1
end
end
end
return closestplyr,closestpos
end
for _, aiparts in pairs(ai:GetChildren()) do
if aiparts:IsA("Part") then
aiparts.Touched:Connect(function(p)
local enemy = p.Parent
if serPlayers:GetPlayerFromCharacter(enemy) then
local ehuman = enemy.Humanoid
ehuman.Health = 0
end
end)
end
end
local path = game:GetService("PathfindingService"):CreatePath({})
local isWandering = 0
game:GetService("RunService").Heartbeat:Connect(function()
local _,enemyp = GetClosestPlayerTo(hroot.Position)
if enemyp then
path:ComputeAsync(hroot.Position, enemyp)
local waypoints = path:GetWaypoints()
local waypoint = waypoints[1]
human:MoveTo(waypoint.Position)
human.Jump = waypoint.Action==1
return
end
human.Jump = false
end)