How do I stop the moving humanoid?

Hi! So I’m trying to make this system where an NPC follows the nearest player. However, I’m also trying to make the NPC stop following the player once the target has died.

Problem: Even though the player has died, the NPC won’t stop moving until the character is actually gone.

I tried using humanoid:MoveTo(rootPart) but it did not work. I’m not sure if I might have placed it in the wrong section.

Any suggestions to fix this are appreciated.

The script in ServerScriptService

local players = game:GetService("Players")
local runService = game:GetService("RunService")

local npcs = workspace:WaitForChild("NPCs")

local targets = {}

players.PlayerAdded:Connect(function(player)

	player.CharacterAdded:Connect(function(char)

		table.insert(targets, char)

		char:WaitForChild("Humanoid").Died:Connect(function()
			table.remove(targets, table.find(targets, char))
		end)

	end)

	player.CharacterRemoving:Connect(function(char)
		table.remove(targets, table.find(targets, char))
	end)

end)

local function getNearestPlayer(npc)

	if not npc:FindFirstChild("Humanoid") then return end

	if #players:GetPlayers() < 1 then
		print("no players found.")
	end

	repeat wait() until #players:GetPlayers() >= 1
	repeat wait() until #targets > 0

	local closest

	local currentPos = npc.PrimaryPart.Position
	local currentTarget = nil

	table.sort(targets, function(a, b)
		return (npc.PrimaryPart.Position - a.PrimaryPart.Position).Magnitude < (npc.PrimaryPart.Position - b.PrimaryPart.Position).Magnitude
	end)

	closest = targets[1]
	currentTarget = closest
	currentPos = npc.PrimaryPart.Position

	closest:WaitForChild("Humanoid").Died:Connect(function()

		currentTarget = nil
		table.remove(targets, 1)

		if #targets == 0 then
			print("no players found.")
			npc.Humanoid:MoveTo(npc.HumanoidRootPart.Position)
			return nil
		end

		closest = targets[1]

	end)

	return closest

end

local function moveNPCToClosest(npc)

	local closestPlayer = getNearestPlayer(npc)
	repeat wait() until closestPlayer ~= nil

	npc.Humanoid:MoveTo(closestPlayer.PrimaryPart.Position)

end

runService.Heartbeat:Connect(function()
	for _, npc in pairs(npcs:GetChildren()) do
		if npc:IsA("Model") and npc:FindFirstChild("Humanoid") then
			moveNPCToClosest(npc)
		end
	end
end)

A simple yet effective way is setting the Humanoid.WalkSpeed equal to 0, and/or anchoring the HumanoidRootPart. Give it a go and see what happens.

2 Likes

this is:
player.CharacterRemoving:Connect(function(char)
table.remove(targets, table.find(targets, char))
end)

If you want to full-stop the character, you should set it’s AssemblyLinearVelocity at X & Z both to 0:

HumanoidRootPart.AssemblyLinearVelocity *= Vector3.new(0, 1, 0)

The code will stop the linear X and Z movement of the character, which is the basic movement on a flat plane. This means the character will cease moving horizontally (forward, backward, and sideways) while retaining any vertical motion, such as jumping or falling.

I’d like to add that you can also cancel the MoveTo operation by calling the same method with the position that the humanoid is already located. There may be another way to do this that I am not aware of but I am doing my research.

Edit: After some quick research, I’ve learned that the MoveTo method simply applies new values to two properties, WalkToPoint and WalkToPart:

You can try to just blank out these properties to stop the movement by using WalkToPoint to Vector3.zero.

2 Likes

So that you understand my post better, you must remove the char parameter from the Died event, I think it is your oversight because it is not necessary, and it will probably interfere with the variable

You are right but I think what he is looking for is for his table search method to work.

1 Like

So there’s another way this can be achieved?

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.