Skip to content

Instantly share code, notes, and snippets.

@thebeardphantom
Last active October 29, 2020 06:27
Show Gist options
  • Save thebeardphantom/b2dfe3c76c80ad70d2deb055b8cf9498 to your computer and use it in GitHub Desktop.
Save thebeardphantom/b2dfe3c76c80ad70d2deb055b8cf9498 to your computer and use it in GitHub Desktop.
An example of a custom graph that extends A* Pathfinding Project to directly use a Unity Tilemap for building nodes and navigation. Also uses https://gist.github.com/thebeardphantom/6a05ef68ce6ce7c890c4a4d9afaccf74
using Pathfinding;
using Pathfinding.Serialization;
using Pathfinding.Util;
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.Tilemaps;
[Preserve]
[JsonOptIn]
public class TilemapGraph : NavGraph
{
#region Types
public class TilemapGraphNode : PointNode
{
#region Fields
public Vector2Int TilemapCell;
#endregion
#region Constructors
public TilemapGraphNode(AstarPath astar) : base(astar) { }
public TilemapGraphNode() { }
#endregion
}
#endregion
#region Fields
public Tilemap WorldTilemap;
private TilemapGraphNode[] _nodes;
#endregion
#region Methods
private static bool CheckNodePositionWalkable(TilemapGraphNode node)
{
return true;
}
/// <inheritdoc />
public override void GetNodes(Action<GraphNode> action)
{
if (_nodes == null)
{
return;
}
foreach (var node in _nodes)
{
action(node);
}
}
/// <inheritdoc />
protected override IEnumerable<Progress> ScanInternal()
{
if (WorldTilemap == null)
{
yield break;
}
WorldTilemap.CompressBounds();
var bounds = WorldTilemap.cellBounds;
var nodeGrid = new Dictionary<Vector2Int, TilemapGraphNode>();
foreach (var tilemapPosition in bounds.allPositionsWithin)
{
if (!WorldTilemap.HasTile(tilemapPosition))
{
continue;
}
var node = new TilemapGraphNode(active)
{
TilemapCell = tilemapPosition.To2D()
};
node.position = GetAStarPosition(node.TilemapCell);
node.Walkable = CheckNodePositionWalkable(node);
nodeGrid.Add(node.TilemapCell, node);
yield return new Progress(0f, "Generating nodes");
}
var connectionList = new List<Connection>(6);
var index = 0;
var nodeCount = nodeGrid.Count;
foreach (var node in nodeGrid.Values)
{
connectionList.Clear();
foreach (var direction in EnumData<HexNeighborDirection>.Values)
{
var neighborCell = node.TilemapCell.GetNeighborCell(direction);
if (nodeGrid.TryGetValue(neighborCell, out var newConnection))
{
connectionList.Add(new Connection(newConnection, initialPenalty));
}
}
node.connections = connectionList.ToArray();
node.SetConnectivityDirty();
yield return new Progress((float) index++ / nodeCount, "Forming connections");
}
_nodes = nodeGrid.Values.ToArray();
}
private Int3 GetAStarPosition(Vector2Int tilemapPosition)
{
return (Int3) (Vector3) WorldTilemap.layoutGrid.GetCellCenterWorld2D(tilemapPosition);
}
#endregion
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment