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