You can write your topic however you want, but you need to answer these questions:
-
What do you want to achieve? Keep it simple and clear!
I have created an A* path and want to achieve 2 things,
- is it possible to remove from open list the nodes that are not adjecent to the current node without ruining my pathfinding? if so how would i do that?
- optimize to make it run faster.
-
What is the issue? Include screenshots / videos if possible!
The issue is that when i remove the nodes that are not adjecent to the current node, the path is getting stuck on walls. -
What solutions have you tried so far? Did you look for solutions on the Developer Hub?
i have tried to add for i,node in pairs(opentable) table.remove(opentable,i) if its not the current and is not adjecent to the current, path is breaking inside the wall.
thi is the project
astar.rbxl (52.2 KB)
I cant find a solution to make it work with less lag between the sessions, i dont want to loop between each waypoint because it wont make my path dynamic
the full code is here:
-- A* Pathfinding Algorithm in Lua (3D with Vector3)
-- Function to calculate the Euclidean distance between two Vector3 points
function calculateDistance(v1, v2)
return (v2 - v1).Magnitude
end
local function roundToStep(pos : Vector3)
return Vector3.new(math.floor(pos.X/3)*3+1.5,math.floor(pos.Y/3)*3+1.5, math.floor(pos.Z/3)*3+1.5)
end
local Blocks = {}
for i,v in pairs(workspace.Map:GetChildren()) do
for x= -v.Size.X / 2 ,v.Size.X / 2-3,3 do
for y= -v.Size.Y / 2 - 6 ,v.Size.Y / 2-3,3 do
for z= -v.Size.Z / 2 ,v.Size.Z / 2-3,3 do
Blocks[roundToStep(v.Position+Vector3.new(x,y,z))] = v
end
end
end
end
-- A* Pathfinding function for 3D grid
function astar3D(start, goal)
start = roundToStep(start)
goal = roundToStep(goal)
local openSet = {start}
local closedSet = {}
local cameFrom = {}
local gScore = {}
local fScore = {}
gScore[start] = 0
fScore[start] = calculateDistance(start, goal)
while #openSet > 0 do
-- Find the node with the lowest fScore in openSet
local current = openSet[1]
for i = 2, #openSet do
if fScore[openSet[i]] < fScore[current] then
current = openSet[i]
end
print(#openSet)
end
-- Goal reached, reconstruct path
if current == goal then
local path = {current}
while cameFrom[current] do
current = cameFrom[current]
table.insert(path, 1, current)
end
return path
end
-- Move current from openSet to closedSet
for i, node in ipairs(openSet) do
if node == current then
table.remove(openSet, i)
break
end
end
--table.insert(closedSet, current)
closedSet[current] = current
-- Explore neighbors
local neighbors = {
current + Vector3.new(3, 0, 0),
current + Vector3.new(-3, 0, 0),
current + Vector3.new(0, 3, 0),
current + Vector3.new(0, -3, 0),
current + Vector3.new(0, 0, 3),
current + Vector3.new(0, 0, -3)
}
for _, neighbor in ipairs(neighbors) do
if closedSet[neighbor] == nil and Blocks[roundToStep(neighbor)] == nil then
local tentative_gScore = gScore[current] + 1 -- Assuming uniform cost for simplicity
if not contains(openSet, neighbor) or tentative_gScore < (gScore[neighbor] or math.huge) then
cameFrom[neighbor] = current
gScore[neighbor] = tentative_gScore
fScore[neighbor] = gScore[neighbor] + calculateDistance(neighbor, goal)
if not contains(openSet, neighbor) then
table.insert(openSet, neighbor)
end
end
end
end
end
-- No path found
return nil
end
-- Helper function to check if a table contains a specific Vector33 element
function contains(table, element)
for _, value in ipairs(table) do
if value == element then
return true
end
end
return false
end
-- Example usage
local start = Vector3.new(1, 1, 1)
local goal = Vector3.new(1, 1, 31)
local obstacles = {}
for i,v in pairs(workspace.Map:GetChildren()) do
table.insert(obstacles, v.Position)
end
local currentPart
while wait(0.1) do
if not currentPart then
print(3)
currentPart = workspace.start
end
local path = astar3D(currentPart.Position, workspace.target.Position)
if path and #path >=2 then
print("Path found:")
local a = Instance.new("Part")
a.Size = Vector3.new(3,3,3)
a.Position = path[2]
a.Anchored = true
a.CanCollide = false
a.Parent = workspace
a.Material = Enum.Material.SmoothPlastic
a.Color = Color3.new(0, 0, 0.498039)
currentPart = a
else
print("No path found.")
end
end