A* Pathfinding Project

Limiting the amount of steps in a turn-based game


#1

Hi everyone!

First of all, I’ve just found this asset, as my project needed it, and it’s awesome.
I’m working on a 2D turn based game, and until now, I’ve managed to achieve that my character can avoid obstacles, so the pathfinding works great.
However I can’t find a solution to stop him after making e.g.10 steps, and to give the control to another character. How could I do that?
Thanks in advance for any help!


#2

Hi

Do you use a custom movement script or one of the built-in ones?


#3

I’m using the built-in AILerp script.


#4

I knows it’s might be a very simple or lame question, but sadly I can’t continue my project until it’s not solved.
So when the path is searched, and I’m getting a log that e.g. “Path Completed : Computation Time 5.00 ms Searched Nodes 89 Path Length 27”, how can I stop my character after making the 10th step from the 27?


#5

Hi

Sorry. I thought I had already answered this thread.

You can do something like this (I haven’t tested this code):

public Seeker seeker;
public AILerp ai;
void TakeStepsTowards(Vector3 point, int steps) {
    ai.canSearch = false;
    AstarPath.StartPath(ABPath.Construct(ai.position, point, (Path p) => {
        if (!p.error) {
            var ab = p as ABPath;
            // Make sure the path contains at most [steps+1] number of nodes
            while(ab.path.Count > steps + 1) ab.path.RemoveAt(ab.path.Count - 1);
            while(ab.vectorPath.Count > steps + 1) ab.vectorPath.RemoveAt(ab.vectorPath.Count - 1);
            // Adjust the end point of the path
            ab.endPoint = ab.originalEndPoint = ab.vectorPath[ab.vectorPath.Count-1];
            // Just to make sure things like ai.reachedDestination will work properly
            ai.destination = ab.endPoint;
            // Post process the path using the Seeker (if you have any modifiers)
            seeker.PostProcess(ab);
            // Make the AI follow the path
            ai.SetPath(ab);
        }
    }));
}

#6

Thank you very much for the answer and for the code example.
However I didn’t manage to get it work, because I’m not sure where should I use it.
Since you’re beginning the code with:

public Seeker seeker;
public AILerp ai;

I suppose I should attach AILerp (and Seeker) script to the character gameobject, and include this code in my character controller script, and find the “seeker” and “ai” in the Start function with

seeker = GetComponent<Seeker> ();
ai = GetComponent<AILerp> ();

Then at the Update function I’m trying to do something like this, but my character still goes all the way.

if (ai.canMove == true) {
TakeStepsTowards (ai.destination, 10);
}

I’ve also tried to add this function to the AILerp script, and tried to call it from the Update, but still no success.
Can you please tell me where and when should I use this code? Thanks.


#7

The code above is intended to be called once when you want the agent to start moving. What it will do is calculate a path to the target and then cut it off to only the first N nodes. Then it will tell the AI to follow that path. So just call that method once when you want the agent to move.

You should place the code in a separate script (e.g. your character controller script) on the agent’s GameObject.


#8

I see. I’d like to move the agent when a new target has been set (the user double clicks with the mouse), so I made a new public int variable in the TargetMover script, called “shouldStartWalking” and I’m setting its value to “1” when a double click has been registered.

Then in my character controller script I’m saying:

if(targetMover.shouldStartWalking == 1){
TakeStepsTowards (ai.destination, 10);
targetMover.shouldStartWalking = 0;
}

Also, I’ve put a debug line into the TakeStepsTowards function to make sure it’s running.
But it’s still not working properly, the agent goes all the way, and here’s the log I’m getting on the console:


#9

Right. Try this instead

public Seeker seeker;
public AILerp ai;
void TakeStepsTowards(Vector3 point, int steps) {
    ai.canSearch = false;
    var path = ABPath.Construct(ai.position, point);
    AstarPath.StartPath(path);
    path.BlockUntilCalculated();
    if (!path.error) {
        // Make sure the path contains at most [steps+1] number of nodes
        while(path.path.Count > steps + 1) path.path.RemoveAt(path.path.Count - 1);
        while(path.vectorPath.Count > steps + 1) path.vectorPath.RemoveAt(path.vectorPath.Count - 1);
        // Adjust the end point of the path
        path.endPoint = path.originalEndPoint = path.vectorPath[path.vectorPath.Count-1];
        // Just to make sure things like ai.reachedDestination will work properly
        ai.destination = path.endPoint;
        // Post process the path using the Seeker (if you have any modifiers)
        seeker.PostProcess(path);
        // Make the AI follow the path
        ai.SetPath(path);
    }
}

The AIDestinationSetter is only intended for simple scenarios where you just want to move towards an object. In your case I’d recommend just using a custom script to call the above function.


#10

Thank you very much, now it works properly!