Pathfinding issues

I’m trying to do pathfinding, but it keeps returning the error message Path not computed! Unable to cast Instance to Vector3. I’ve looked for a while now, and I can’t really figure out why.

Module script with functions:

--variables
local players = game:GetService("Players")
local pathfindingService = game:GetService("PathfindingService")

local entityStats = require(game.ServerScriptService.entityStats)

local pathNodes = {}
for i, v in pairs(workspace.aiTest.map.rooms:GetChildren()) do
	if v.nodes.pathNode then
		table.insert(pathNodes, v.nodes.pathNode)
	end
end

--functions
local functions = {}

function functions.pursue(entity, player)

end

function functions.patrol(location, entity, previousNode)
	local path = pathfindingService:CreatePath({
		AgentRadius = entityStats[location].pathfindingRadius,
		AgentHeight = entityStats[location].pathfindingHeight,
		AgentCanJump = false,
		AgentCanClimb = false
	})

	--node selection
	local closestPathNodes = {}
	local selectedPathNodeKey
	local selectedPathNode
	if previousNode == nil then
		--get random node
		selectedPathNodeKey = math.random(#pathNodes)
		selectedPathNode = pathNodes[selectedPathNodeKey]
	else
		--get 3 closest previous nodes
		for i, v in pairs(pathNodes) do
			local magnitude = (previousNode.Position - v.Position).Magnitude

			closestPathNodes[v] = magnitude
		end

		for nodeValue = 1, #closestPathNodes do
			if nodeValue > 3 then
				table.remove(closestPathNodes, 4)
			end
		end

		--pick random node from 3 closest
		selectedPathNodeKey = math.random(#closestPathNodes)
		selectedPathNode = closestPathNodes[selectedPathNodeKey]
	end

	--pathfinding
	local waypoints
	local nextWaypointIndex
	local reachedConnection
	local blockedConnection
	
	local success, errorMessage = pcall(function()
		path:ComputeAsync(entity.HumanoidRootPart.CFrame.Position, selectedPathNode)
	end)

	if success and path.Status == Enum.PathStatus.Success then
		-- Get the path waypoints
		waypoints = path:GetWaypoints()

		-- Detect if path becomes blocked
		blockedConnection = path.Blocked:Connect(function(blockedWaypointIndex)
			-- Check if the obstacle is further down the path
			if blockedWaypointIndex >= nextWaypointIndex then
				-- Stop detecting path blockage until path is re-computed
				blockedConnection:Disconnect()
				-- Call function to re-compute new path
				functions.patrol(location, entity, previousNode)
			end
		end)

		-- Detect when movement to next waypoint is complete
		if not reachedConnection then
			reachedConnection = entity.Humanoid.MoveToFinished:Connect(function(reached)
				if reached and nextWaypointIndex < #waypoints then
					-- Increase waypoint index and move to next waypoint
					nextWaypointIndex += 1
					entity.Humanoid:MoveTo(waypoints[nextWaypointIndex].Position)
				else
					reachedConnection:Disconnect()
					blockedConnection:Disconnect()
				end
			end)
		end

		-- Initially move to second waypoint (first waypoint is path start; skip it)
		nextWaypointIndex = 2
		entity.Humanoid:MoveTo(waypoints[nextWaypointIndex].Position)
	else
		warn("Path not computed!", errorMessage)
	end
end

function functions.spawn(specificEntity)
	--call function with custom entity
	local selectedEntity
	if specificEntity == nil then
		--random entity
		--add natural entities to table
		local naturalEntities = {}
		for i, v in pairs(entityStats) do
			if v.natural then
				table.insert(naturalEntities, i)
			end
		end

		--determine entity odds
		local entityOddsTable = {}
		for i, v in pairs(naturalEntities) do
			local chosenEntity = entityStats[v]
			local entityRarity = chosenEntity.rarity

			for rarity = entityRarity, 1, -1 do
				table.insert(entityOddsTable, v)
			end
		end

		--pick random entity from entity selection table
		local selectedEntityKey = math.random(#entityOddsTable)
		selectedEntity = entityOddsTable[selectedEntityKey]
	else
		selectedEntity = specificEntity
	end
	
	print(selectedEntity)
	
	--pick node to spawn
	local selectedPathNodeKey = math.random(#pathNodes)
	local selectedPathNode = pathNodes[selectedPathNodeKey]
	
	--spawn entity
	local entity = entityStats[selectedEntity].location:Clone()
	entity:PivotTo(CFrame.new(
		selectedPathNode.Position.X,
		selectedPathNode.Position.Y + (entityStats[selectedEntity].pathfindingHeight / 2) - .5,
		selectedPathNode.Position.Z
	))
	entity.Parent = workspace.aiTest.map.activeEntities
	
	--start patrolling
	functions.patrol(selectedEntity, entity)
end

return functions

Module scripts with tables:

local entities = {
	amalgamation = {
		location = "game.ServerStorage.entities.amalgamation",
		pathfindingRadius = 0,
		pathfindingHeight = 0,
		
		walkspeed = 6,
		runspeed = 22,
		damage = math.huge,
		firerate = 2,
		range = 4,
		sight = 0,
		hearing = 60,
		
		chaseTheme = "rbxassetid://0",
		jumpScareSound = "rbxassetid://0",
		
		rarity = 10,
		natural = true
	},
	
	buffoon = {
		location = "game.ServerStorage.entities.buffoon",
		pathfindingRadius = 0,
		pathfindingHeight = 0,

		walkspeed = 14,
		runspeed = 28,
		damage = math.huge,
		firerate = .75,
		range = 2,
		sight = 40,
		hearing = 34,
		
		chaseTheme = "rbxassetid://0",
		jumpScareSound = "rbxassetid://0",
		
		rarity = 10,
		natural = true
	},
	
	cacophony = {
		location = "game.ServerStorage.entities.cacophony",
		pathfindingRadius = 0,
		pathfindingHeight = 0,

		walkspeed = 8,
		runspeed = 15,
		damage = 60,
		firerate = .75,
		range = 4,
		sight = 34,
		hearing = 38,

		chaseTheme = "rbxassetid://0",
		jumpScareSound = "rbxassetid://0",

		rarity = 10,
		natural = true
	},
	
	doppelganger = {
		location = "game.ServerStorage.entities.doppelganger",
		pathfindingRadius = 0,
		pathfindingHeight = 0,

		walkspeed = 14,
		runspeed = 20,
		damage = math.huge,
		firerate = 4,
		range = 4,
		sight = math.huge,
		hearing = 26,

		chaseTheme = "rbxassetid://0",
		jumpScareSound = "rbxassetid://0",

		rarity = 10,
		natural = true
	},
	
	dummy = {
		location = game.ServerStorage.entities.dummy,
		pathfindingRadius = 4,
		pathfindingHeight = 5.5,
		
		walkspeed = 14,
		runspeed = 22,
		damage = math.huge,
		firerate = 1,
		range = 2,
		sight = 32,
		hearing = 64,

		chaseTheme = "rbxassetid://0",
		jumpScareSound = "rbxassetid://0",

		rarity = 0,
		natural = false
	},
	
	enigma = {
		location = "game.ServerStorage.entities.enigma",
		pathfindingRadius = 0,
		pathfindingHeight = 0,

		walkspeed = 16,
		runspeed = 20,
		damage = math.huge,
		firerate = 0,
		range = 2,
		sight = 48,
		hearing = 24,

		chaseTheme = "rbxassetid://0",
		jumpScareSound = "rbxassetid://0",

		rarity = 10,
		natural = true
	},
	
	gander = {
		location = "game.ServerStorage.entities.gander",
		pathfindingRadius = 0,
		pathfindingHeight = 0,

		walkspeed = 12,
		runspeed = 40,
		damage = math.huge,
		firerate = 1,
		range = 2,
		sight = 38,
		hearing = 0,

		chaseTheme = "rbxassetid://0",
		jumpScareSound = "rbxassetid://0",

		rarity = 10,
		natural = true
	},
	
	marionette = {
		location = "game.ServerStorage.entities.marionette",
		pathfindingRadius = 0,
		pathfindingHeight = 0,

		walkspeed = 14,
		runspeed = 18,
		damage = math.huge,
		firerate = 0,
		range = 1,
		sight = math.huge,
		hearing = 40,

		chaseTheme = "rbxassetid://0",
		jumpScareSound = "rbxassetid://0",

		rarity = 10,
		natural = true
	},
	
	myriad = {
		location = "game.ServerStorage.entities.myriad",
		pathfindingRadius = 0,
		pathfindingHeight = 0,

		walkspeed = 10,
		runspeed = 14,
		damage = 20,
		firerate = 1,
		range = 2,
		sight = 30,
		hearing = 16,

		chaseTheme = "rbxassetid://0",
		jumpScareSound = "rbxassetid://0",

		rarity = 10,
		natural = true
	},
	
	myriadServant = {
		location = "game.ServerStorage.entities.myriadServant",
		pathfindingRadius = 0,
		pathfindingHeight = 0,

		walkspeed = 12,
		runspeed = 16,
		damage = 5,
		firerate = .66,
		range = 1,
		sight = 26,
		hearing = 14,

		chaseTheme = "rbxassetid://0",
		jumpScareSound = "rbxassetid://0",

		rarity = 0,
		natural = false
	},
	
	phantom = {
		location = "game.ServerStorage.entities.phantom",
		pathfindingRadius = 0,
		pathfindingHeight = 0,

		walkspeed = 6,
		runspeed = 6,
		damage = 5,
		firerate = .25,
		range = 6,
		sight = math.huge,
		hearing = 0,

		chaseTheme = "rbxassetid://0",
		jumpScareSound = "rbxassetid://0",

		rarity = 10,
		natural = true
	},
	
	purgatory = {
		location = "game.ServerStorage.entities.purgatory",
		pathfindingRadius = 0,
		pathfindingHeight = 0,

		walkspeed = 10,
		runspeed = 14,
		damage = math.huge,
		firerate = 0,
		range = 2,
		sight = 36,
		hearing = 30,

		chaseTheme = "rbxassetid://0",
		jumpScareSound = "rbxassetid://0",

		rarity = 10,
		natural = true
	},
	
	thermostat = {
		location = "game.ServerStorage.entities.thermostat",
		pathfindingRadius = 0,
		pathfindingHeight = 0,

		walkspeed = 16,
		runspeed = 20,
		damage = 5,
		firerate = 0.05,
		range = 0.1,
		sight = 48,
		hearing = 24,

		chaseTheme = "rbxassetid://0",
		jumpScareSound = "rbxassetid://0",

		rarity = 0,
		natural = false
	}
}

return entities

Script that calls functions:

local entityStats = require(game.ServerScriptService.entityStats)
local entityFunctions = require(game.ServerScriptService.entityFunctions)

entityFunctions.spawn("dummy")

I want the functions to be easily customizable so I can use the same function for pathfinding on all of the different entities, so if I’m approaching anything incorrectly or weirdly, feel free to let me know!

Edit: Changed name from previous draft oops

1 Like

Does the error give the line where its happening?

1 Like

the error is returned in the pcall function in the patrol function so it has to do with something in the pcall function

1 Like

Looking through your code it looks like selectedPathNode is set to either a number (distance between 2 nodes) or an Instance (v.nodes.pathNode).
If it’s set to the Instance (and its a part), make sure to put selectedPathNode.Position instead.

I’m assuming this is the issue considering your error says “Unable to cast Instance to Vector3”.
Let me know if you still need any help :slight_smile:

1 Like