I am working on a new project and I need some advice on which graph to use. The requirements or needs are the following:
The game takes place on a on the XY plane done with 2D Tiles which will create a spaceship. Player will be able to build tiles at runtime and expand it. The spaceship will move so the graph should be able to rotate along with it (not sure if posible). Collisions are done in 2D and you see everything as if a platformer with a cutout to see inside the ship. There will be two graphs, one for when theres gravity and they need to pathfind along the “ground” and another when at zero G so they can float around (as if the game had a topview).
I am confused as to which graph would better fit my project requirements. Any advice would be greatly appreciated.
Thanks in advance!
If any features required by the project needs a Pro licence I can get it.
At the moment Ive been trying with the free version and grid graphs, the problem is I cannot rotate the graph along the Z axis (view vector).
Manuel
Hi
That will work fine with e.g a grid graph.
This package does unfortunately not have support for platformer type pathfinding. It is possible to get something working with point graphs, but it requires quite a lot of custom code. I think there is another package on the Unity Asset store that explicitly provides platformer pathfinding (but nothing else).
It is usually much easier to move the camera or the rest of the world. It is possible to move the graph (see A* Pathfinding Project: GridGraph Class Reference), but it is a quite heavy operation as it requires recalculating the positions for every node in the graph.
1 Like
Thanks Aron for the quick reply! Ive been trying with point and grid graphs and I think I got a better idea on how to use them. I noticed there is a “moving” example in the pro version (which I ended up buying since yours is the best solution for pathfinding out there) and I think I can get it working for my main spaceship instead of moving the camera and the world (which I tried before seeing the example scene and was working rather well I must say).
My question is, since there will be other objects floating in space that astronauts need to know how to pathfind inside them to investigate while doing extra vehicular activities, could I build a point graph for each object and then use that graph “locally”? Convert from world to local space. So an object will leave the spaceships grid and start using the objects grid when they are close enough to it, and pathfind using the spaceships when they return. Am I thinking about this in the right way? Would you care to give me any pointers on the right direction?
Thank you in advance for your time!
The main problem with using the approach in the ‘Moving’ scene is that graph updates are going to be tricky. The ‘Moving’ example scene handles pathfinding correctly, however if you need to update the graph it will still try to check for collisions at the origin graph position.
You can connect graphs using off-mesh links. Take a look at the NodeLink2 component (sorry about the naming of those components, the off-mesh links are unfortunately the part of the package that I am the least happy with). So you could connect your point graph and your grid graph. I recommend that you keep the overlap between the point graph and the grid graph to an absolute minimum as the agents can become very confused if there are multiple different graphs close to them. Since the spaceship is also moving it might be tricky to keep the links updated. If possible I would recommend that there are no links at all. Agents will automatically use the closest graph to their current position.
1 Like
Still trying to write a LocalSpaceAILerp script, no luck so far, but I am learning the system little by little, if anyone has done this before some help would be greatly appreciated
Just out of curiosity if two graphs overlap, is there a way to tell the agent to use one or the other specifically?
Yes, the seeker.StartPath method has an optional ‘graphMask’ parameter.
Here is the documentation for it: A* Pathfinding Project
1 Like
Thank you Aron! Big part of why I decided to get Astar was because of how active and helpful you are to everyone!
I was wondering if you could help me out. I am trying to get the LocalSpaceAILerp component working, this is what I have so far. The problem is when I move the ship the graph gets out of sync eventually, and the movement is jerky at best, tried doing it every frame without much success. Sorry to bother you.
public override void ForceSearchPath () {
if (target == null) throw new System.InvalidOperationException("Target is null");
lastRepath = Time.time;
var targetPosition = target.position;
var currentPosition = GetFeetPosition();
if (path != null && path.vectorPath.Count > 0) {
currentPosition = path.vectorPath[currentWaypointIndex];
}
canSearchAgain = false;
// We should search from the current position in graph local space
Matrix4x4 m = graph.GetMatrix();
seeker.StartPath(m.MultiplyPoint3x4(currentPosition), m.MultiplyPoint3x4(targetPosition));
}
public override void OnPathComplete (Path _p) {
ABPath p = _p as ABPath;
Matrix4x4 m = graph.GetMatrix();
Matrix4x4 mi = m.inverse;
// convert the result to world space from graph space
for (int i = 0; i < p.vectorPath.Count; i++) {
p.vectorPath[i] = mi.MultiplyPoint3x4(p.vectorPath[i]);
}
if (p == null) throw new System.Exception("This function only handles ABPaths, do not use special path types");
canSearchAgain = true;
// Claim the new path
// This is used for path pooling
p.Claim(this);
// Path couldn't be calculated of some reason.
// More info in p.errorLog (debug string)
if (p.error) {
p.Release(this);
return;
}
if (interpolatePathSwitches) {
ConfigurePathSwitchInterpolation();
}
// Release the previous path
// This is used for path pooling
if (path != null) path.Release(this);
// Replace the old path
path = p;
// Just for the rest of the code to work, if there is only one waypoint in the path
// add another one
if (path.vectorPath != null && path.vectorPath.Count == 1) {
path.vectorPath.Insert(0, GetFeetPosition());
}
targetReached = false;
// Reset some variables
ConfigureNewPath();
}
Think it has something to do with scale of the ship not being 1.0f across the board and the ship not being at the origin at the beginning.
Found part of the solution. For anyone else out there that needs to do something similar. In LocalSpaceGraph the GetMatrix() function matrix multiplication should be reversed so it takes into account scale and position of the starting object, that way it does not need to be positioned at the origin with a scale of 1 at the start.
public Matrix4x4 GetMatrix() {
return originalMatrix * transform.worldToLocalMatrix;
}
Ah. Yes, I found that bug just a few weeks ago. It has already been fixed in version 4.0 and it might make it into 3.8 when I backport some changes.
The other part of the solution is likely that you are converting the waypoints to world space in the OnPathComplete method. That means that the waypoints are only correct during the frame in which the path was calculated, during subsequent frames the ship will have moved but the path will not move with it. Try instead to keep the waypoints in graph space and transform them to world space during every frame.
1 Like