As you can probably tell, I am trying to achieve something simple, an NPC that is able to follow the closest player. This part works perfectly, but unfortunately, I’ve had a problem.
The NPC stutters while running after the player. Sometimes it stops stuttering and then starts again but I’m not sure if that is relevant. I think this problem is allied with the Renderstepped and MoveTo events/functions. Please let me know what you think.
Part of tScript:
local heartbeat = RunService.Heartbeat:Connect(function()
task.wait()
local players = game.Players:GetPlayers()
for i,enemy in pairs(self.Models) do
enemy.Parent = workspace
local target = nil
local minValue = nil
for i,player in pairs(players) do
local char = player.Character
local distance = (enemy.HumanoidRootPart.CFrame.Position - char.HumanoidRootPart.CFrame.Position).magnitude
if minValue == nil then
minValue = distance
target = char
print("min value hahahhaa " .. minValue)
print("target lol" .. target.Name)
else
if minValue > distance then
minValue = math.min(minValue, distance)
target = char
else
print("nonono")
end
print(distance)
print(minValue)
print(target)
end
end
enemy.Humanoid:MoveTo(target.HumanoidRootPart.Position)
end
end)
Use the roblox’s :moveTo example code and change it a bit:
local function moveTo(humanoid, targetPoint, andThen)
local targetReached = false
-- listen for the humanoid reaching its target
local connection
connection = humanoid.MoveToFinished:Connect(function(reached)
targetReached = true
connection:Disconnect()
connection = nil
if andThen then
andThen(reached)
end
end)
-- start walking
humanoid:MoveTo(targetPoint)
-- execute on a new thread so as to not yield function
task.spawn(function()
while not targetReached do
-- does the humanoid still exist?
if not (humanoid and humanoid.Parent) then
break
end
-- has the target changed?
if humanoid.WalkToPoint ~= targetPoint then
break
end
-- refresh the timeout
humanoid:MoveTo(targetPoint)
task.wait(6)
end
-- disconnect the connection if it is still connected
if connection then
connection:Disconnect()
connection = nil
end
end)
end
local function andThen(reached)
print((reached and "Destination reached!") or "Failed to reach destination!")
end
moveTo(script.Parent:WaitForChild("Humanoid"), Vector3.new(50, 0, 50), andThen)
--If the enemy's stud is less than the distance then
if (enemy.HRP.Position - char.Humanoid.Position).magnitude < distance then
target = enemy.HRP
--Create Ray
local origin = char.Humanoid.Position -- Origin of the ray
local direction = enemy.HRP.Position - char.Humanoid.Position -- direction of the ray
local params = RaycastParams.new() --Ray cast params
params.FilterDescendantsInstances = {script.Parent}
params.FilterType = Enum.RaycastFilterType.Blacklist
local ray = workspace:Raycast(origin, direction,params)
if ray then
char:MoveTo(target.Position) --If ray, then the character will move to the target
end
end