- Home /
Stuck with A* Pathfinding Script
I've posted this question on Stack Exchange, but I'm not getting much help. Hopefully there's a pathfinding guru somewhere on this forum who can help me out! The question:
I'm using Sebastian Lagues' pathfinding system found in these tutorials: https://www.youtube.com/playlist?list=PLFt_AvWsXl0cq5Umv3pMC9SPnKjfp9eGW.
I've started extending his code for a dynamic RTS type game, but I've run into a problem. The units do not land on the target node, but one node before. This is problematic as for my game I need the units to land directly on the target node.
I'm usually happy to solve problems alone, but I don't even know where to begin fixing this. The project is found here (episode 5): https://github.com/SebLague/Pathfinding
Thanks in advance for any help or suggestions.
Answer by HenryStrattonFW · Feb 16, 2017 at 07:53 PM
Success! ok so I had a look over it, had to take a few parts out one by one to work out where the issue was coming from, I've found it!.
In the Simplify path method you start your for loop from index 1 (so that you can always do i-1 to i for direction). However because of this, path[0] never makes it through the simplify stage, and always get culled out of the list. So all i did was update the Simplify method add path[0] to the waypoints list just before the for loop starts up.
(Note I did still have the previous addition mentioned in my answer, I'm unsure why this causes you issues, but in any case it does not appear to make a difference to the final target location).
Thanks a lot! For the last couple of days I've been using some hacky code that moved the unit to the target node when they reached the end of the path. I really wanted that to happen by default, so I really appreciate the help. I'm using this pathfinding code as part a Simple RTS series I'm doing on youtube. If you're interested, I'd appreciate any critical feedback. You can find the tute and a link to the project here: https://www.youtube.com/watch?v=OqADgd05fpQ
Happy to help. Gave the video a quick look and it looks good, could be a very useful series for some people. A few things that you do differently to how I would do them. For example, you have a Unit class, which to me would be a good place to store a reference to the selection circle, and then expose a method on the unit like "SetSelected(bool)" for turning it on/off, to me this way feels more flexible, and cleaner, but that could just be more down to personal preference as the way you are doing it is perfectly functional
That being said, you asked for critical feedback and there was one thing that you commented on a few times in the video regarding how Get$$anonymous$$ouseButtonDown worked, and how you could not put for loops inside that statement because it is only present for one frame. I'll be blunt, what I understood you to be saying in that regard is completely wrong. You could put as much logic as you wanted in that statement and it will all be processed, because the next frame of the game will not occur until that code completes. Granted I would advise not putting anything that is hugely computationally expensive in there to avoid lag spikes (perhaps this is what you meant, if so feel free to ignore this whole section), but for the purposes of iterating over a list to add/remove units, unless dealing with a huge number of units, or insanely costly actions as part of your deselection/selection logic I see no reason that you could not put this logic within that if statements scope.
Thanks a lot for the feedback! I should express those statements more tentatively in future. I guess I just assumed that's how it worked as when I put the for loop that ran through all the units and deselected them in the getmousebutton down if statement, only some were deselected. I had to click the ground a couple of times for them all to be deselected.
There must be another cause for this behaviour, although I'm not sure what it is. I should probably start another forum post about it. I'll put a link to the question here if you ever get a chance to look into it. Thanks again for solving this issue and for the helpful feedback :)
Answer by HenryStrattonFW · Feb 15, 2017 at 10:25 PM
I've not downloaded the project to try, but had quick look at the source on github and there's one thing that jumps out at me as a likely cause, your retrace function.
Vector3[] RetracePath(Node startNode, Node endNode) {
List<Node> path = new List<Node>();
Node currentNode = endNode;
while (currentNode != startNode) {
path.Add(currentNode);
currentNode = currentNode.parent;
}
Vector3[] waypoints = SimplifyPath(path);
Array.Reverse(waypoints);
return waypoints;
}
Notice that once currentNode == startNode you break out of the while loop, but in doing so do not then add the currentNode to the path, meaning that "startNode" never makes it into the list. so once reversed you would be 1 node short.
Try adding a path.Add(CurrentNode);after your while loop before you simplify your path, and see if that sorts it out, unless that node is being added to the list elsewhere and I missed it, this should solve the problem.
Thanks for the reply! Unfortunately, adding the currentNode there creates an index out of range exception when the character reaches the end of the path.
downloaded now, oddly enough I do not get a null ref when I add the start node, however I also do not seem to get the units to sit on top of the target node either, they still seem to stop one early.
I'll have a deeper look into it and let you know if I work it out.
Your answer
Follow this Question
Related Questions
Distribute terrain in zones 3 Answers
RTS Grid Initialisation 0 Answers
A* Pathfinding Project Problem with Obstacles 2 Answers
Astar Pathfinding not scanning graph 0 Answers
Multiple Cars not working 1 Answer