Skip to content

Instantly share code, notes, and snippets.

@rubenhorn
Last active October 29, 2019 17:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rubenhorn/0a64650c5d767c6e096482f6d3f7f30e to your computer and use it in GitHub Desktop.
Save rubenhorn/0a64650c5d767c6e096482f6d3f7f30e to your computer and use it in GitHub Desktop.
A Unity3d script emulating a power network
using System.Collections.Generic;
using UnityEngine;
public class EnergySource : MonoBehaviour
{
public float maxEdgeLength = 1.0f;
public string vertexTag = "GraphVertex";
private TransformGraph<GameObject> graph = new TransformGraph<GameObject>();
void Start()
{
// Reset
graph.ClearVertices();
// Add all "objects" that should be connected in the graph
foreach(var vGO in GameObject.FindGameObjectsWithTag(vertexTag)){
graph.AddVertex(vGO.transform, vGO);
}
// Calculate connections
graph.ComputeEdges(maxEdgeLength);
// Check which "objects" in the graph can be reached from this "object"
graph.TraverseEdgesFromSource(transform);
// Mark all reachable "objects"
foreach(var visitedVertex in graph.visitedVertices) {
if(visitedVertex == transform) {
// ...but not the starting point
continue;
}
GameObject vGO = graph.verticesData[visitedVertex];
vGO.GetComponent<Renderer>().material.color = Color.red;
}
}
void OnDrawGizmos() {
// Draw connections in graph
if(graph != null) {
foreach(var edge in graph.edges) {
Gizmos.DrawLine(edge.from.position, edge.to.position);
}
}
}
}
using System.Collections.Generic;
using UnityEngine;
// Warning! This is not very efficient and should not be used in every Update or with many vertices
public class TransformGraph<T> {
public struct Edge {
public readonly Transform from, to;
public Edge(Transform from, Transform to) {
this.from = from;
this.to = to;
}
}
public Dictionary<Transform, T> verticesData = new Dictionary<Transform, T>();
public HashSet<Edge> edges = new HashSet<Edge>();
public HashSet<Transform> visitedVertices = new HashSet<Transform>();
public void ClearVertices() {
verticesData.Clear();
}
public void AddVertex(Transform transform, T data) {
verticesData.Add(transform, data);
}
public void ComputeEdges(float maxEdgeLength) {
edges.Clear();
var vertices = new List<Transform>();
foreach(var vertex in verticesData.Keys) {
vertices.Add(vertex);
}
while(vertices.Count > 0) {
var a = vertices[0];
vertices.RemoveAt(0);
foreach(var b in vertices) {
if(Vector3.Distance(a.position, b.position) <= maxEdgeLength) {
edges.Add(new Edge(a, b));
}
}
}
}
public void TraverseEdgesFromSource(Transform source) {
visitedVertices.Clear();
List<Transform> startVertices = new List<Transform>();
visitedVertices.Add(source);
startVertices.Add(source);
while(startVertices.Count > 0) {
Transform startVertex = startVertices[0];
startVertices.RemoveAt(0);
foreach(var edge in edges) {
Transform neighbor = null;
if(edge.from == startVertex) {
neighbor = edge.to;
}
else if(edge.to == startVertex) {
neighbor = edge.from;
}
if(neighbor != null && !visitedVertices.Contains(neighbor)){
visitedVertices.Add(neighbor);
startVertices.Add(neighbor);
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment