How to build an AR prototype in Unity

Stephan Gensch
Nov 16, 2018 · 9 min read
A 1:500 scale model of inner city Berlin in the foreground, and a 1:1000 scale larger area of Berlin in the background.

Types of visualization

Getting data — area, lines and points of interest

Show, don't tell

Building density in inner city Berlin from the FIS Broker
Gradient shader
Simple semi-transparent shader with color variation
Area visualization of average building density per living-oriented space.

Ride the streets of Berlin

{
"type": "Feature",
"properties": {
"STRSCHL": "1605",
"STR_NAME": "Goethestraße",
"BEZIRKE": "Charlottenburg-Wilmersdorf",
"LAENGE": 939.26,
[ ... OMMITTED FOR READABILITY ... ]
"ABDECKUNG": 0.0,
[ ... OMMITTED FOR READABILITY ... ]
},
"geometry": {
"type": "MultiLineString",
"coordinates": [
[
[ 13.3192, 52.508958662336752 ],
[ 13.319448764861379, 52.508962989456393 ],
[ 13.319554453283571, 52.508952001315976 ],
[ 13.319803551156319, 52.508937697178176 ],
[ 13.320032190971109, 52.508923102030579 ],
[ 13.320316359267492, 52.508909294780977 ],
[ 13.322634081280583, 52.508785167882053 ],
[ 13.32290629904543, 52.508766556885412 ],
[ 13.32500968897619, 52.508669822693989 ],
[ 13.325171474800982, 52.508686845616928 ]

]
]
}
},
Vector3 coord = Quaternion.AngleAxis(coords[i].longitude, -Vector3.up) * Quaternion.AngleAxis(-coords[i].latitude, -Vector3.right) * new Vector3(0, 0, -6371.0f);
Set up of a tiny world core and an outer world shell of roughly a 1:1000 scale within Unity.
Tiny blob of lines on an idealized spherical body.
Used an offset to rotate the world origin and an anchor element to be able to adjust its relative position.
"Radmesser" project data visualized on our digital model.
Projection and model: everything is nicely in the same scale.
// Array of all routes with key=start time and bike GameObject
private SortedDictionary<DateTime, List<GameObject>> routesDict;
// add current route to sorted dictionary
if (routesDict.ContainsKey(fromTime))
{
List<GameObject> goList;
if (routesDict.TryGetValue(fromTime, out goList))
{
goList.Add(go);
}
}
else
{
List<GameObject> goList = new List<GameObject>();
goList.Add(go);
routesDict.Add(fromTime, goList);
}
foreach (KeyValuePair<DateTime, List<GameObject>> route in routesDict)
{
// start with current time of 2015-06-03 00:00:00
while (currentTime < route.Key)
{
currentTime = currentTime.AddSeconds(Time.deltaTime * SPEEDUP_FACTOR);
time.text = currentTime.Hour.ToString("00") + ":" + currentTime.Minute.ToString("00");
yield return null; // to interrupt the coroutine
}
foreach (GameObject go in route.Value)
{
go.SetActive(true);
Bike compBike = go.GetComponent<Bike>();
StartCoroutine(compBike.AnimateAlongPath());
count.text = currentCount++.ToString();
}
}
See the bikes being animated in the app (link to stores above).

Tear down this Wall

Points of interest in Berlin: Checkpoint Charlie and the Berlin Wall Memorial site.

What did we learn?

Thanks to Vragments

Stephan Gensch

Written by

Computer Scientist & Journalism Technologist | Berlin | Co-founder & CPO Vragments GmbH | Part-time Deutsche Welle ReCo

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade