Improved Pathfinding Algorithms

Hey everyone,

I’d appreciate some feedback on where to go with this pathfinding issue I have. I’m building the ARAM game mode from League of Legends and pretty much have some general melee minions and caster minions setup as well as a few towers.

The general logic for the minions is below:

while Figure.Parent ~= nil do
   -- yield loop for 0.5 seconds
   -- find nearest enemy
   --[[ if enemy exists and is in range then
             attack
        elseif enemy exists then
             go to their position
       else
            go to enemy towers / nexus and attack if in range
   ]]--
end

One problem is that my pathfinding continuously computes a path, causing the model to stutter step in the animation. I’m computing the path in the parts where it says go to in my pseudocode but I’m wondering if this part could be improved.

A second issue I have is that the pathing is set to the root position of the model so there could be random path blocks / clipping because the minions shouldn’t be able to jump over each other. I’m thinking the best solution for this is to find the closest point right outside the model’s size but not sure how to design or approach this problem. For example, a minion should be just standing next to the nexus (20x20) and be attacking it if it is a melee unit.

Thanks!

Hmm, I’m quite confused on this part, what exactly do you mean?

I call a function in my pathing module to follow a target so it continuously computes a path towards it. However, my animation is basically looking like it stutter steps so I wonder if it’s a problem with the walking animation or if I’m re computing the path too many times. I had designed the continuous computes so that if the target position changes, the path would basically get updated. Here’s a sample video of what happens with the current pathing algorithm. In my testing, I did find that the path gets blocked but am really not sure why. The minions are trying to walk from where they are to the square block you see in the corner of the video.

1 Like

I originally thought it was because you’re starting up the animation too fast (spamming :Play()), but it seems not. It’s most likely because of the computed path, make sure nothing in the model has a part where it collides with the character (blocking the path).

You probably are right with how I’m treating the Nexus. It’s basically a Model with a humanoid and a part where the part is a 20x20 square. I’m just not sure how I could fix the pathing so units can attack it when they are in range.

Well first off, you don’t need a part that’s a 20x20 square.
You can just go through enemies, and check the distance between the (enemy) and the unit.
And then there’s your target.

The part that is the 20x20 square is the Nexus. The objective is to destroy it so I need it as part of the game. I’ll be updating the part with a mesh later.

1 Like

Ohhh.
Nevermind then. Sorry. .

Does your pathing process use a whitelist to exclude anything you can ignore?
When processing the pathfinding does it use a method to ensure only one pathfinding process is running at a time?
When following the path check if the distance to the target is within range and if so stop moving.

Hello, I had the same issue, for me It helped to set the network owner of HumanoidRootPart to nil.
Figure.HumanoidRootPart:SetNetworkOwner(nil)

No the path is continuously computed in case the target moves. It’s a generic pathing function that targets either minions (other moving models) or the stationary towers / nexus. I could try redoing my pathing algorithm so that it updates the path if the position of the target changes instead of continuously computing a path. However, I still have the problem where I’m trying to path to the center of a large part instead of getting inside attack range of the target.

I don’t really know much of pathfinding but see if this could help?
It’s a year late but the topic seemed dead without a solution

The code isn’t much efficent, generally loops are usually not the answer.

local PathfindingService = game:GetService("PathfindingService")
local Figure = ...

local function FindNearestEnemy()
 -- guessing you have your own function for this
end

local path = PathfindingService:CreatePath({
	AgentCanJump = false, -- set to true if you want them to jump over obstacles
	Costs = {
		Water = math.huge, -- You can put stuff you wanna avoid in a list here
	}
})

while Figure.Parent ~= nil do
    if FindNearestEnemy then
        local EnemyPrimaryPart = FindNearestEnemy.PrimaryPart -- whatever you'd put here
        local success, err = pcall(function()
            path:ComputeAsync(Figure.PrimaryPart.Position, EnemyPrimaryPart.Position)
        end)
    end

    if success and path.Status == Enum.PathStatus.Success then
        local waypoints = path:GetWaypoints()
        humanoid:MoveTo(waypoints[2].Position)
        humanoid.MoveToFinished:Wait()
    else
        print(err)
    end
end
1 Like