How the Query system in Unity MARS does procedural layout

The Query system in Unity MARS simplifies the creation of augmented reality (AR) experiences that adapt to the real world around them. Based on constraints that you specify, it finds a way to lay out the scene in a given environment. Read on to learn more about how it works.

We designed Unity MARS to help creators make context-adaptable AR. We hoped to solve the primary issues AR developers face: defining content relative to the real world, iteration time and testing in environments, and adapting the way virtual content is laid out in varying real-world environments. We call this the adaptable content problem.

Queries are Unity MARS’ way of solving the adaptable content problem. For each distinct piece (or group of pieces) of virtual content that needs to integrate into a place in the real world, Unity MARS devises a query – a request for semantically tagged data that describes part of the real world. Queries have two high-level pieces:

One or more conditions that define what data can match the query One or more actions that specify what to do when Unity MARS finds a match

Each query is created either by a Proxy, which represents the link between the virtual content and the real world, or by multiple proxies in a Proxy Group.

Data entities

Each entry in the Unity MARS Database represents a single part of the real-world environment around the user. These parts can take many forms – some of the most common are surfaces, faces, and image markers.  

Each one of these entries is identified by a number called a data ID. They also can have any number of traits – named properties of a given data type. This model is conceptually similar to an entity component system – each trait is like a component. 

Data usage

Each proxy has a property called Exclusivity, which determines how it will use the data it matches against, and limits how the query handles trying to match against data that is already in use. Keeping track of data that’s already used allows the user to make sure different pieces of content go to different pieces of the real world. There are three exclusivity settings:

Reserved is asking for exclusive access to this data – it needs to not already be in use by a Shared or Reserved proxy, and after it matches, it can only be used by other proxies in a read-only manner.   Shared is asking to use this data, but not exclusively – other Shared proxies can already be using it, and use it after it matches. Read Only can always access any data, since it declares that it will not “use up” the option.  

After a query matches, all the proxies within it are marked as “using” that piece of data in the manner their exclusivity specifies.  


Every condition takes into account a single trait of the data it’s considering, and determines whether or not it fits the criteria.  One of the primary benefits of authoring a Condition against a trait, such as position or size, instead of directly against trackable data like surfaces or faces, is that they are re-usable for any data that has that same trait.  

Consider the Plane Size condition as an example.

It requires the trait “bounds2d, which

Continue reading

This post was originally published on this site