Applying Basic 2D Layer-based Penalties

Hello,

Similar to this post:

I’m looking to apply penalties to my 2D Tilemap based on Layers (aka “Roads” layer are faster than “Grass” layer).

I’ve gone ahead and tried to write a simple script to do this, basically trying to emulate the functionality that the Pathfinder script uses to take the Obstacle Layer Mask and find impassable areas.

This is what my code looks like:

public class TilePenaltyModifier : GraphModifier
{
    public bool ApplyOnScan = true;
    public LayerMask RoadLayer;

    public override void OnPostScan()
    {
        if (ApplyOnScan)
        {
            ScanGraph();
        }
    }

    private void ScanGraph()
    {
        if (AstarPath.active == null) 
        {
            Debug.LogError("There is no AstarPath object in the scene", this);
            return;
        }

        AstarPath.active.AddWorkItem(new AstarWorkItem(ctx => {
            GridGraph gridGraph = AstarPath.active.data.gridGraph;
            for (int z = 0; z < gridGraph.depth; z++)
            {
                for (int x = 0; x < gridGraph.width; x++)
                {
                    GraphNode node = gridGraph.GetNode(x, z);

                    RaycastHit2D[] hits = Physics2D.RaycastAll((Vector3)node.position, Vector2.zero);
                    
                    foreach (RaycastHit2D hit in hits)
                    {
                        if (hit &&
                        (1 << hit.collider.gameObject.layer) == RoadLayer.value)
                        {
                            Debug.Log($"Layer hit at {(Vector3)node.position}");
                        }
                    }
                }
            }
        }));
    }
}

The issue is, this doesn’t appear to be actually hitting my “Road” layer for some reason.

My question: does the Pathfinder script use raycasts to figure out Obstacles, or is there an easier way to be doing the above?

I figured this out - ended up using TileMap.GetTile() rather than RayCast2D and it’s working well.

1 Like