Currently, I’m trying to make an NPC that tracks what moves (like “James” in “Identity Fraud” in Roblox’s game), but once I have the basics of the script, I try to move it. Only the first detected block is tracked without detecting other than the first detected block.
Eventually I want to detect other blocks as well. How can we improve it? Thank you.
local PathfindingService = game:GetService("PathfindingService")
entity = nil
distanceofentity = nil
firstsetup = true
local myoidrootpart = script.Parent:WaitForChild("HumanoidRootPart")
local myhumanoid = script.Parent:WaitForChild("Humanoid")
while wait(0) do
local childreninworkspace = game.Workspace:GetChildren()
for i,workchild in pairs(childreninworkspace) do
if workchild:IsA("Part") or workchild:IsA("MeshPart") or workchild:IsA("UnionOperation") then
if workchild.Velocity == Vector3.new(0,0,0) then
else
local distofchild = (script.Parent.HumanoidRootPart.Position - workchild.Position).magnitude
if entity == nil and distanceofentity == nil then
firstsetup = false
entity = workchild
distanceofentity = distofchild
elseif distanceofentity > distofchild and firstsetup == false then
entity = workchild
distanceofentity = distofchild
end
end
elseif workchild:IsA("Model") then
local childrenofworkchild = workchild:GetChildren()
for i,childchild in pairs(childrenofworkchild) do
if childchild:IsA("Part") or childchild:IsA("MeshPart") or childchild:IsA("UnionOperation") then
local childofme = script.Parent:GetChildren()
for i,v in pairs(childofme) do
if v:IsA("Part") or v:IsA("MeshPart") or v:IsA("UnionOperation") then
if not v == childchild then
if childchild.Velocity == Vector3.new(0,0,0) then
else
local distofchild = (script.Parent.HumanoidRootPart.Position - childchild.Position).magnitude
if entity == nil and distanceofentity == nil then
firstsetup = false
entity = childchild
distanceofentity = distofchild
elseif distanceofentity > distofchild and firstsetup == false then
entity = childchild
distanceofentity = distofchild
end
end
end
end
end
end
end
end
end
print(entity,", ",distanceofentity)
if entity == nil then
else
local path = PathfindingService:CreatePath()
path:ComputeAsync(myoidrootpart.Position, entity.Position)
local waypoints = path:GetWaypoints()
for i, waypoint in pairs(waypoints) do
myhumanoid:MoveTo(waypoint.Position)
myhumanoid.MoveToFinished:Wait()
end
end
end
Instead of assigning entity throughout the loop, you could just spawn a function to move the humanoid when the entity is detected, rather than assigning it to the entity variable, it will run asynchronously from the loop and not halt anything.
dummy code
while wait() do
detect humanoid stuff blah blah
is it the right distance blah blah
declare what the humanoid is here locally
spawn(function()
move the humanoid
this will run without halting the code
end)
end
end
end
This is just a quick way i could think of, this is by no means the best method or such.
This would at least cut out a big chunk of the code and prevent halting, it will also ensure that it always moves the detected entity and not only the last one declared.
@OP, I honestly believe using too many loops might cause performance issues, but I’m not 100% sure. There’s too much to explain here, I’ll just spoonfeed.
local PathfindingService = game:GetService("PathfindingService")
local Entity
local DistanceOfEntity
local FirstSetup = true
local HRP = script.Parent.HumanoidRootPart
local Hum = script.Parent.Humanoid
while wait(.2) do
local WorkspaceChildren = game.Workspace:GetChildren()
for _, Child in ipairs(WorkspaceChildren) do
if Child:IsA('BasePart') then
if Child.Velocity ~= Vector3.new(0,0,0) then
local Distance = (HRP.Position - Child.Position).Magnitude
if not Entity and not DistanceOfEntity then
FirstSetup = false
Entity = Child
DistanceOfEntity = Distance
elseif DistanceOfEntity > Distance and FirstSetup == false then
Entity = Child
DistanceOfEntity = Distance
end
end
elseif Child:IsA("Model") then
local ChildChildren = Child:GetChildren()
for _, ChildChild in pairs(ChildChildren) do
if ChildChild:IsA('BasePart') then
local CharacterChild = script.Parent:GetChildren()
for _, ChildOfCharacter in ipairs(CharacterChild) do
if ChildOfCharacter:IsA('BasePart') then
if ChildOfCharacter ~= ChildChild then
if ChildChild.Velocity ~= Vector3.new(0,0,0) then
local Distance = (HRP.Position - ChildChild.Position).Magnitude
if not Entity and not DistanceOfEntity then
FirstSetup = false
Entity = Child
DistanceOfEntity = Distance
elseif DistanceOfEntity > Distance and FirstSetup == false then
Entity = Child
DistanceOfEntity = Distance
end
end
end
end
end
end
end
end
end
print(Entity,", ",DistanceOfEntity)
if Entity then -- Computes path
local NewPath = PathfindingService:CreatePath()
NewPath:ComputeAsync(HRP.Position, Entity.Position)
local Waypoints = NewPath:GetWaypoints()
for _, Waypoint in ipairs(Waypoints) do
Hum:MoveTo(Waypoint.Position)
Hum.MoveToFinished:Wait()
end
end
end