[Augmented Reality with Unity & Azure Spatial Anchors Series - Part 8] - Persisting Scenery



Jim Mc̮̑̑̑͒G
  ·  
4 May 2020  
  ·  
 4 min read

This is part eight of a nine-part series that explores how to create a Unity application for a mobile device, using Augmented Reality and Azure Spatial Anchors

  • In Part 1 we introduce the project, requirements, technologies and various AR concepts.
  • In Part 2 we follow the steps in the project QuickStart guide.
  • In Part 3 we create a basic Unity ARFoundation application.
  • In Part 4 we look at one of the building blocks of AR - the “Placement Cursor”.
  • In Part 5 we explore how the UI for the project works.
  • In Part 6 we learn how Azure Spatial Anchors can be used in our project.
  • In Part 7 we step up our game by looking at how we can add and move virtual scenery.
  • In Part 8 we develop functionality that saves and restores virtual scenery to the cloud.
  • In Part 9 we learn about the Azure Functions backend for the solution.

The entire project sourcecode that accompanies this series can be found at:



In this article, we’ll be looking at how we go about saving and retrieving the layout of the “scenery” objects using cloud storage.

This will enable us to:

  • return to the same physical location at a later time and restore the same layout
  • enable other people, using their own mobile devices, to share the same experience at the same time.



Applicable code in this article:



screenshot of spatialanchorgroup

Saving scenery

  • The entry point to this part of the code is through the method SaveScenery() in the SceneryPersistenceManager Component.
    • This method is called by the UI “Save Scenery” button - we can find the code for that the UIManager Component, in UIButton_SaveScenery_Click().


An overview of the process that saves “scenery” objects to cloud storage is:

  • the user taps the UI “Save Scenery” button
  • code in SaveScenery():
    • creates a DTO object that will be used as part of the string-serialisation process.
      • the overall DTO comprises a “container” object which has a list of multiple “items”.
      • each “item” in DTO essentially represents the Pose of an individual “scenery” object, using a selection of float arrays.
  • code in MapSceneryGameobjectsToDTO():
    • iterates over the “scenery” GameObjects in Unity, which are children of the container GameObject SpatialAnchorGroup/SceneryContainer
    • populates DTO items with information such as the sceneryTypeEnum which is used to determine whether the scenery is, for example, an “oak-tree” or a “poplar tree”.
  • TransformComponentDTO class is used to:
    • model the Pose data
    • provides a constructor which extracts Pose data from the Transform of each object of “scenery”
  • the DTO is serialised to JSON using the built-in Unity JsonUtility library.
  • the Unity Coroutine method PostSceneryDataJsonToApi() is used to make an HTTP POST to our own API.
    • we specify the Url to our API in the Unity Editor, in the “GeneralConfiguration/apiUrl_SceneData” field.

Note: We’ll look at the Azure Functions backend part of this project in the final article of this series: Part 9 - Cloud Backend


Gotcha: If you are adapting this project and decide to create your own DTO classes, do not create fields that include a {get; set;} because the Unity JsonUtility does not like them and will break!



screenshot showing 3d scenery

Restoring scenery

  • The entry point to this part of the code is through the method RestoreScenery() in the SceneryPersistenceManager Component.
    • This method is called by the UI “Restore Scenery” button - we can find the code for that the UIManager Component, in UIButton_esScenery_Click().


An overview of the process that saves “scenery” objects to cloud storage is:

  • the user taps the UI “Restore Scenery” button
  • the Unity Coroutine method GetSceneryDataFromApi() is used to make an HTTP GET to our own API - a JSON result is returned.
  • the byte array response from the API is mapped into the SceneryItemContainerDTO DTO object.
  • list of “scenery” items modelled in the DTO is iterated upon
  • SpawnNewScenery() method is used to
    • spawn an appropriate new GameObject by referring to the enumeration SceneryTypeEnum
    • add it to the scene with necessary Transforms.
    • set the parent to be the anchor “SceneryContainer”



Next, in the final part of the series, we learn about the Azure Functions backend for the solution.

NEXT: Read part 9

If you find my content helpful, please consider sharing the love with a GitHub Sponsorship - equivalent to a cup of coffee every other week.





Archives

2020 (23)
2019 (27)