How can I make MoveTo work on client?

So I want to make a NPC that only 1 person can see if that makes sense so client. but i dont really know how to do it.

my code:

local Robot = script.Parent
local Humanoid = Robot.Humanoid

local PathFindingService = game:GetService("PathfindingService")
Robot.PrimaryPart:SetNetworkOwner(nil)

local attacked = false

local function findTarget()
	local players = game.Players:GetPlayers()
	local maxDistance = 40
	local nearestTarget
	
	for i, player in pairs(players) do
		if player.Character then
			local target = player.Character
			local distance = (Robot.HumanoidRootPart.Position - target.HumanoidRootPart.Position).Magnitude
			
			if distance < maxDistance then
				nearestTarget = target
				maxDistance = distance
			end
		end
	end
	
	return nearestTarget
end

local function getPath(destination)
	local path = PathFindingService:CreatePath()
	path:ComputeAsync(Robot.HumanoidRootPart.Position, destination.Position)
	
	return path
end

local function attack(target)
	-- test
	
	local distance = (Robot.HumanoidRootPart.Position - target.HumanoidRootPart.Position).Magnitude
	
	if distance > 2.5 then
		Humanoid:MoveTo(target.HumanoidRootPart.Position)
	else
		if attacked == false then
			attacked = true
			target.Humanoid:TakeDamage(5)
			task.wait(0.25)
			attacked = false
		end
	end
end

local function walkTo(destination)
	local path = getPath(destination)
	
	for i, waypoint in pairs(path:GetWaypoints()) do
		local target = findTarget()
		
		if target then
			print("Target: "..target.Name)
			attack(target)
			
			break
		else
			Humanoid:MoveTo(waypoint.Position)
			Humanoid.MoveToFinished:Wait()
		end
	end
end

local function patrol()
	local wayPoints = workspace.World.RobotWaypoints:GetChildren()
	local randomNum = math.random(1, #wayPoints)
	
	walkTo(wayPoints[randomNum])
end

while task.wait() do
	patrol()
end

This is server script but when i try to change it to local script it doesnt work

MoveTo:() does in fact work on the client. Where are you putting the localscript? You’d have to set the RunContext of a normal script to Client instead of actually using a localscript if its in the workspace. If you choose Client as the RunContext, you basically have a local script, but it will run almost anywhere, including in the workspace.

3 Likes

i did that and it still doesnt work. the script is in workspace

Does the script work when the RunContext is set to Server or to Legacy?

yeah just doesnt work when on client

To make MoveTo work on the client, you can use a RemoteEvent to communicate between the client and the server.

--Server Script (ServerScriptService):
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local PathfindingService = game:GetService("PathfindingService")

local MoveToRemoteEvent = Instance.new("RemoteEvent")
MoveToRemoteEvent.Name = "MoveToRemoteEvent"
MoveToRemoteEvent.Parent = ReplicatedStorage

local function getPath(destination)
	local path = PathfindingService:CreatePath()
	path:ComputeAsync(destination, destination)
	return path
end

MoveToRemoteEvent.OnServerEvent:Connect(function(player, destination)
	local path = getPath(destination)

	for _, waypoint in pairs(path:GetWaypoints()) do
		MoveToRemoteEvent:FireClient(player, waypoint.Position)
	end
end)
--Client Script (StarterPlayer > StarterPlayerScripts):
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local player = game.Players.LocalPlayer

local MoveToRemoteEvent = ReplicatedStorage:WaitForChild("MoveToRemoteEvent")

MoveToRemoteEvent.OnClientEvent:Connect(function(destination)
	local humanoid = player.Character and player.Character:FindFirstChildOfClass("Humanoid")
	if humanoid then
		humanoid:MoveTo(destination)
	end
end)

Hope that gets you a bit closer. GL!

You’ll need to make a remote in ReplicatedStorage called MoveToRemoteEvent to get this to work.

1 Like

EDIT: Nope i was wrong sorry, I confused the two scripts

Are there any errors in the output?

nope no errors

(IGNORE: ADOWAJKODKAD)

Try adding some print statements to check if any of your variables are nil.
(Such as path, nearestTarget, wayPoints etc.

The NPC has to be “owned” by the client so just

Robot:SetNetworkOwnership(player.LocalPlayer)

when i print path i get Instance in the output

did that and it still didnt work sadly and it gives me error (NET WORK OWNERSHIP CAN ONLY BE CHANGED ON SERVER)

One thing that works for me is just shove the Robot in Replicated Storage, and move all of the server script to a local script in StarterPlayerScripts. Just make that script clone the robot and put it in workspace. And obviously just change the :FireServer() to the MoveTo()

I also did that and still didnt work

Loaded it into my world and did this:

task.wait(1)
local Robot = game.ReplicatedStorage:WaitForChild('Robot'):Clone()
Robot.Parent = workspace
local Humanoid = Robot.Humanoid

local PathFindingService = game:GetService("PathfindingService")

local attacked = false

local function findTarget()
	local players = game.Players:GetPlayers()
	local maxDistance = 40
	local nearestTarget

	for i, player in pairs(players) do
		if player.Character then
			local target = player.Character
			local distance = (Robot.HumanoidRootPart.Position - target.HumanoidRootPart.Position).Magnitude

			if distance < maxDistance then
				nearestTarget = target
				maxDistance = distance
			end
		end
	end

	return nearestTarget
end

local function getPath(destination)
	local path = PathFindingService:CreatePath()
	path:ComputeAsync(Robot.HumanoidRootPart.Position, destination.Position)

	return path
end

local function attack(target)
	-- test

	local distance = (Robot.HumanoidRootPart.Position - target.HumanoidRootPart.Position).Magnitude

	if distance > 2.5 then
		Humanoid:MoveTo(target.HumanoidRootPart.Position)
	else
		if attacked == false then
			attacked = true
			target.Humanoid:TakeDamage(5)
			task.wait(0.25)
			attacked = false
		end
	end
end

local function walkTo(destination)
	local path = getPath(destination)

	for i, waypoint in pairs(path:GetWaypoints()) do
		local target = findTarget()

		if target then
			print("Target: "..target.Name)
			attack(target)

			break
		else
			Humanoid:MoveTo(waypoint.Position)
			Humanoid.MoveToFinished:Wait()
		end
	end
end

local function patrol()
	local wayPoints = workspace.World.RobotWaypoints:GetChildren()
	local randomNum = math.random(1, #wayPoints)

	walkTo(wayPoints[randomNum])
end

while task.wait() do
	patrol()
end

Just make sure Robot is parented to ReplicatedStorage and the script is parented to StarterPlayerScripts!
(you can remove the task.wait(1) at the beginning if you want, I just added it to let things load)

1 Like

tysm it works perfectly!

(IGNORE: DAIOJWID0AJW)

Yay! Glad to hear it helped!
–Extra characters…–

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