UGTK cat mascotUGTKengine within an engine Request access

UGTK / Toolkit / Utility Systems / Graph System Completed

Utility Systems — UGTK

Graph System

Summary

The Graph System is a generic, serializable graph data structure (Graph<T>) built from Node<T> and weighted Edge<T>. It offers traversal (BFS / DFS) and pathfinding (Dijkstra and A*), plus grid/strategy helpers like reachable-within-cost and farthest-nodes.


Content


Modules Dependencies

This module has no hard UGTK dependencies (pure C# data structure).


Setup

No scene setup, no component, no prefab: it is a plain C# data structure, so there is nothing to show in a GIF. Instantiate Graph<T> from code and populate it with nodes and edges.

The classes live in the global namespace (Graph<T>, Node<T>, Edge<T>), so no using is needed — but those are very common names: watch out for collisions with other packages.


How To Use

var graph = new Graph<string>();
graph.AddNode("A");
graph.AddNode("B");
graph.AddNode("C");
graph.AddEdge("A", "B", 1);
graph.AddEdge("B", "C", 5);

graph.Bfs("A");                                  // logs the BFS order
graph.DFS("A");                                  // logs the DFS order

List<Node<string>> path = graph.FindShortestPathByDijkstra("A", "C");
List<Node<string>> aStar = graph.AStar("A", "C"); // uses HeuristicCostEstimate (override for a real heuristic)

var reachable = graph.GetReachableNodesWithinCost(graph.GetNodeContainsValue("A"), 3);

For A, subclass Graph<T> and override HeuristicCostEstimate(node1, node2) to provide a real heuristic (the base returns 0, making A behave like Dijkstra). Nodes can be marked non-traversable via Node<T> (BecomeUntraversable() / BecomeTraversable() / IsTraversable()), which A*, reachable and farthest queries respect.

Good to know:


Testing Scene

Open Debug/GraphSystemScene.unity. It holds one object, GraphSystemTest, carrying Mn_GraphSystemTest. Everything happens in the Inspector: right-click the component header and the seven entries of its context menu appear. No play mode, no wiring.

What to do, in order:

  1. Build Grid — a 5×5 grid of nodes named "x,y", wired to their four neighbours with weight 1. Twenty-five nodes, forty edges.
  2. Find Path Dijkstra and Find Path AStar — both return nine nodes for a cost of 8. On a uniform grid the two agree; A* gets there having visited fewer nodes, which is the whole point of the heuristic.
  3. Find Reachable — every node within Movement Budget steps. With a budget of 3 that is ten nodes, and it is the call a tactics game uses to paint the movement range.
  4. Block Node — closes the node named in Node To Block, 2,0 by default, which sits on the straight path.
  5. Find Path AStar again — the route now goes 0,0 → 1,0 → 1,1 → 2,1 → 3,1 → 4,1 → …, around the closed node, at the same cost of 8. Blocking changes the shape of the graph without rebuilding it.
  6. Unblock Node puts it back.

Two things worth knowing, both visible here. Traversability is a property of the node, not of the edges, so closing a door costs one call and no rebuild. And the search does not check the start node: block the node you are standing on and the path still comes back, because the algorithm starts from it rather than entering it.


Technical Info


© 2026 Marcello De Bonis. All rights reserved