Last active
October 29, 2020 06:27
-
-
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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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