Click to move pathfinding

I am currently implementing a move system in my mmo game that will allow players to click and move. I want their character to stop moving if they get within a certain radius of a minion or player to auto attack.

The issue is that my code works on a blank baseplate; however, when it is in my actual map, it bugs out and doesn’t know where my character is trying to go.

I have been browsing through the API references and some devforum posts, but I have yet to see a simple solution. Any help is greatly appreciated.

-- Import services
local ContextActionService = game:GetService("ContextActionService")
local TeamService = game:GetService("Teams")
local Players = game:GetService("Players")
local player = Players.LocalPlayer
local mouse = player:GetMouse()

local human = game.Workspace[player.Name]:WaitForChild("Humanoid")
local head = script.Parent:WaitForChild("Head")

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local enableMovementEvent = ReplicatedStorage:WaitForChild("EnableMovementEvent")

local enemyValue = 0
local walkingEnabled = false

-- Red team is on team 1. Blue team is on team 2.
-- Get the team the player is on
if player.TeamColor == BrickColor.new("Persimmon") then
	enemyValue = 2
else
	enemyValue = 1
end

local ATTACK_RANGE = 20

function walkToClick()
	if walkingEnabled then
			-- Check if walkpoint is an enemy
		if mouse.Target and mouse.Target.Parent:FindFirstChild("Minionoid") and mouse.Target.Parent.Head.EnemyValue.Value == enemyValue then 
			-- Walk to enemy
			local enemyPosition = mouse.Target.Parent.Head.Position
			walkToEnemy(enemyPosition)
		else
		 	-- Walk to point
			walkToPoint(mouse.Hit.X, mouse.Hit.Z)
		end
	end

end

function walkToEnemy(enemyPos)
	local goalX = enemyPos.X
	local goalZ = enemyPos.Z
	local goalPosition = Vector3.new(enemyPos.X, 0, enemyPos.Z)	
	
	local path = game:GetService("PathfindingService"):CreatePath()
	path:ComputeAsync(head.Position, goalPosition)
	local waypoints = path:GetWaypoints()	

	if path.Status == Enum.PathStatus.Success then
		for _, waypoint in pairs(waypoints) do
			if (head.Position - enemyPos).Magnitude > ATTACK_RANGE then
				print((head.Position - enemyPos).Magnitude)
				human:MoveTo(waypoint.Position)
				human.MoveToFinished:Wait()
				head.Position = script.Parent.Head.Position
			end
		end
	else
        print("Path unsuccessful")
       -- wait(2)
	end

	attackEnemy()
end

function walkToPoint(x, z)
	local goalX = x
	local goalZ = z
	local goalPosition = Vector3.new(x, 0, z)
	
	local path = game:GetService("PathfindingService"):CreatePath()
	path:ComputeAsync(head.Position, goalPosition)
	local waypoints = path:GetWaypoints()	

	if path.Status == Enum.PathStatus.Success then
		for _, waypoint in pairs(waypoints) do
			human:MoveTo(waypoint.Position)
			human.MoveToFinished:Wait()
			head.Position = script.Parent.Head.Position
		end
	else
        print("Path unsuccessful")
        wait(2)
	end
end

function attackEnemy()
	
end

function movementControls(allowedToMove)
	if allowedToMove then
		walkingEnabled = true
	end
end

ContextActionService:BindActionAtPriority("Walk", walkToClick, false, Enum.ContextActionPriority.Medium.Value, Enum.UserInputType.MouseButton2)
enableMovementEvent.OnClientEvent:Connect(movementControls)
2 Likes

Any chance you can print path.Status? It’ll give a general idea of what’s wrong and where to look.

It does say Path.Status.Success sometimes, but others it says no path. Could map orientation be messing with the pathfinding system?

Try going into studio settings and enable the navmesh. If there’s nothing wrong with the navmesh, then it’s probably an issue with your script. If, for some reason, the navmesh isn’t updated with your current map, try deleting it and re-pasting it back in.


The nav mesh looks like it should be working. The script works on a blank baseplate though. That’s why I am confused

I think I have figured out a solution that works perfectly with my game type. Since the player can only move with their mouse, I can just make the sides CanCollide = false, and they won’t be able to pass through it ironically.