A* Pathfinding Project

GraphUpdateShape for 2D games


#1

I’m working on a top-down 2d dungeon crawler. I added GraphUpdateObjects to various environmental setPieces (pits, spikes, etc) such that in their start routine they update the tags for the nodes they overlap.

var bounds = GetComponent().bounds;
bounds.Expand(.6f); //Tags the points surrounding the spike to make sure Enemies give them a wide berth.
guo = new GraphUpdateObject(bounds);

    guo.modifyTag = true;
    guo.setTag = spikeTag;
    guo.updatePhysics = false;
    AstarPath.active.UpdateGraphs(guo);

This worked fine, until I needed to rotate my spikes and pit traps. So I tried to add GraphUpdateShapes:

    //Get local points based on the collider
    GetBoxCollider2DPointsLocal(collider, out Vector3[] points);

    Matrix4x4 matrix = transform.localToWorldMatrix;
    var shape = new GraphUpdateShape(points, true, matrix, .1f);
    guo.shape = shape;

    AstarPath.active.UpdateGraphs(guo);

And it’s not working. I see a 4 year old post that GraphUpdateShapes were build to only work in the XZ plane. What can I do in light of that?

I rooted around in GraphUpdateShapes, and saw it was using XZ functions from VectorMath and Polygon, so I attempted to create an XY version of GraphUpdateShapes.Contains, but it doesn’t work, and it’s so mathy, I don’t know where to begin.


#2

Aha! I seem to have solved it by overriding GraphUpdateShape afterall.

After I added an XY vesion Polygon.ConvexHullXY, and CalculateConvexHull, alongside my XY Contains, it seems to work fine.


#3

Hi

Sorry for the late answer.
The GraphUpdateShape does work for 2D as well, however what you need to do is to ensure that all points are projected down to XZ space when clipping happens.

I think something like this would work with the unmodified GraphUpdateShape code.

// Get local points based on the collider
GetBoxCollider2DPointsLocal(collider, out Vector3[] points);

// I'm not sure how you have oriented your transform, but I think this will work for a 2D game
Matrix4x4 matrix = Matrix4x4.TRS(transform.position, Quaternion(-90, 0, 0), Vector3.one);
// I'm not sure what GetBoxCollider2DPointsLocal does, but if it just returns points in local space with respect to the transform, this will
// change them so that they are in local space with respect to the above matrix. You can probably do this in an easier way if you modify GetBoxCollider2DPointsLocal.
Matrix4x4 fixMatrix = matrix.inverse * transform.localToWorldMatrix;
for (int i = 0; i < points.Length; i++) points[i] = fixMatrix.MultiplyPoint3x4(points[i]);
var shape = new GraphUpdateShape(points, true, matrix, .1f);
guo.shape = shape;

AstarPath.active.UpdateGraphs(guo);