Last active
October 29, 2019 17:41
-
-
Save rubenhorn/0a64650c5d767c6e096482f6d3f7f30e to your computer and use it in GitHub Desktop.
A Unity3d script emulating a power network
This file contains 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 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); | |
} | |
} | |
} | |
} |
This file contains 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 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