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* pathfinding Script that works great based on this tutorial:
Improving our A* (Part 2)
The target is a part in the workspace and the start position is the NPC humanoid rootpart which gets updated every time the npc reached its previous node.
Here is the code for the script:
- What is the issue? Include screenshots / videos if possible!
When i move the part while the code is running, Studio freezes for few seconds then i get errors. Which i dont understand why they happen.
-
What solutions have you tried so far? Did you look for solutions on the Developer Hub?
I am stumped, i dont know what to do since i dont understand why i keep getting the errors.
-- Priority Queue (Min-Heap) Implementation
local PriorityQueue = {}
PriorityQueue.__index = PriorityQueue
function PriorityQueue.new()
return setmetatable({ heap = {} }, PriorityQueue)
end
function PriorityQueue:Push(node, priority)
table.insert(self.heap, {node = node, priority = priority})
self:BubbleUp(#self.heap)
end
function PriorityQueue:Pop()
local root = self.heap[1]
local last = table.remove(self.heap)
if #self.heap > 0 then
self.heap[1] = last
self:BubbleDown(1)
end
return root.node
end
function PriorityQueue:BubbleUp(index)
local parentIndex = math.floor(index / 2)
if parentIndex > 0 and self.heap[index].priority < self.heap[parentIndex].priority then
self.heap[index], self.heap[parentIndex] = self.heap[parentIndex], self.heap[index]
self:BubbleUp(parentIndex)
end
end
function PriorityQueue:BubbleDown(index)
local leftChildIndex = index * 2
local rightChildIndex = index * 2 + 1
local smallest = index
if leftChildIndex <= #self.heap and self.heap[leftChildIndex].priority < self.heap[smallest].priority then
smallest = leftChildIndex
end
if rightChildIndex <= #self.heap and self.heap[rightChildIndex].priority < self.heap[smallest].priority then
smallest = rightChildIndex
end
if smallest ~= index then
self.heap[index], self.heap[smallest] = self.heap[smallest], self.heap[index]
self:BubbleDown(smallest)
end
end
function PriorityQueue:IsEmpty()
return #self.heap == 0
end
-- A* Pathfinding in ROBLOX with Vector3 Nodes of Size 3 and Priority Queue
local function Heuristic(a, b)
return (math.abs(a.X - b.X) + math.abs(a.Y - b.Y) + math.abs(a.Z - b.Z))
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 offsets = {
Vector3.new(3, 0, 0), Vector3.new(-3, 0, 0),
Vector3.new(0, 3, 0), Vector3.new(0, -3, 0),
Vector3.new(0, 0, 3), Vector3.new(0, 0, -3),
Vector3.new(3, 0, 3), Vector3.new(3, 0, -3),
Vector3.new(-3, 0, 3), Vector3.new(-3, 0, -3)
}
local function AStar(start, goal)
local openSet = PriorityQueue.new()
openSet:Push(start, 0)
local cameFrom = {}
local gScore = {[start] = 0}
local fScore = {[start] = Heuristic(start, goal)}
while not openSet:IsEmpty() do
local current = openSet:Pop()
if current == goal then
local totalPath = {current}
while cameFrom[current] do
current = cameFrom[current]
table.insert(totalPath, 1, current)
end
return totalPath
end
for _, offset in pairs(offsets) do
local neighbor = roundToStep(current + offset)
local inPart = #workspace:getPartBoundsInRadius(neighbor, 0.2) > 0
if inPart == false then
local tentative_gScore = gScore[current] + (neighbor - current).Magnitude
if not gScore[neighbor] or tentative_gScore < gScore[neighbor] then
cameFrom[neighbor] = current
gScore[neighbor] = tentative_gScore
fScore[neighbor] = gScore[neighbor] + Heuristic(neighbor, goal)
openSet:Push(neighbor, fScore[neighbor])
end
end
end
end
return {}
end
while task.wait() do
local path = AStar(roundToStep(script.Parent.HumanoidRootPart.Position), roundToStep(workspace.Target.Position))
if path and path[3] then
script.Parent.Humanoid:MoveTo(path[3])
script.Parent.Humanoid.MoveToFinished:Wait()
end
end
this is the place file
TestAStar.rbxl (71.2 KB)
Please do not ask people to write entire scripts or design entire systems for you. If you can’t answer the three questions above, you should probably pick a different category.