docs.unity3d.com
    Show / Hide Table of Contents

    Traits

    A Trait in Unity MARS is a semantically meaningful piece of data. Traits have a name and an associated data type. Traits are used to add custom tagged data to the MARS Database. A Proxy matches an entity in the database when the entity's Traits fulfill the Proxy's Conditions and Relations. Proxies with complex conditions and relations can use Synthetic Traits to do things like mark the corners of a room or tag chairs. You can also use a MARS Reasoning API to automatically add Trait(s) to existing entities like how the Floor Reasoning API adds the Floor Trait to the floor plane of a room.

    In this section, we will cover the traits included in MARS, semantic tags, and how to add trait requirements to your proxy both via the editor and through scripting. We will also cover how to define your own custom trait types and how to add your custom trait type to MARS.

    Semantic tags

    Semantic tags are a specific type of trait which tags data with a descriptive label. The "plane" trait is a semantic tag and labels data as an AR plane. Semantic tag traits have a bool value which must be true for the tag to have an effect. You can set the SemanticTagCondition to Match or Exclude the tag. Match means that the data must include the given semantic tag trait for a successful match. Exclude means that the Proxy only matches if the data does not include the tag.

    Standard traits

    Unity MARS includes many common traits (listed below). You can add your own custom types to the database.

    Trait Type Notes
    pose Pose position and rotation
    alignment MarsPlaneAlignment vertical/horizontal/none
    bounds2d Vector2 extents of available 2D space
    markerid string id of this marker
    geolocation GeographicCoordinate latitude and longitude of geographic location
    environment bool is this the user's immediate environment
    face bool is this a face
    inView bool is this in view
    marker bool is this a marker
    plane bool is this a plane
    point bool is this a point
    user bool is this a user
    body bool is this a body

    Adding trait requirements to Proxies

    To add a trait requirement to a Proxy, click the Add MARS Component button, then select Condition > Semantic Tag or Trait and select the tag or trait you want your Proxy to require.

    Adding traits to a Proxy

    Adding trait requirements via scripts

    In code, you can use the IRequiresTraits<T> interface to request and access those traits in matching data objects. Any requirements that actions specify have the resulting value for the trait put into the appropriate dictionary in the QueryResult, where actions can then access them to do their work. If the trait is optional, the action doesn't prevent a Proxy without that trait from matching. For more information about actions, see Writing Actions.

    To define a trait requirement, use a TraitDefinition and specify whether it's optional or not. By default, trait requirements are not optional. For example:

    var nonOptionalRequirement = new TraitRequirement(TraitDefinitions.Pose);
    var optionalRequirement = new TraitRequirement(TraitDefinitions.Bounds2D, false);
    

    Providing traits via scripts

    Classes that implement IProvidesTraits<T> have access to the extension method AddOrUpdateTrait(int dataID, string traitName, T value) that you can use to associate traits with particular data IDs. To create a data ID in the first place, use AddOrUpdateData, which comes from IUsesMARSTrackableData.

    Classes that implement IRequiresTraitshave access to the extension method TryGetTraitValue.

    You can perform Create, Update, and Delete operations on any trait in the system. For more information, see documentation on Reasoning APIs.

    Custom trait types

    It's possible to use your own data types as a trait value.

    Trait types must be a struct, not a class (except for strings). This is because a trait should be a property of a single entity (like a surface or face) and not a reference to another object. They also should only have other value types as fields, not reference types.

    Example

    Here's what a simple custom trait type representing the lighting estimate for a surface might look like.

    in SurfaceLightTrait.cs:

    public struct SurfaceLightTrait
    {
        public float Confidence;
        public float SurfaceBrightnessEstimate;
    }
    

    Plus, a condition that uses that surface lighting data type.

    Writing a Condition or Relation that uses your type is how Unity MARS knows that you want to use it as a trait.

    in SurfaceBrightnessCondition.cs:

    public class SurfaceBrightnessCondition : Condition<SurfaceLightTrait>
    {
        public override float RateDataMatch(ref SurfaceLightTrait data)
        {
            // Here you would have real rating logic, this is just a stub
            return data.Confidence - 0.5f;
        }
    
        static readonly TraitRequirement[] k_RequiredTraits = { new TraitRequirement("surfaceBrightness", typeof(SurfaceLightTrait)) };
        public override TraitRequirement[] GetRequiredTraits() => k_RequiredTraits;
    

    Adding your type

    For Unity MARS to use your type as a trait, it must compile your type into its assembly and generate some code.

    To make that happen, move the file containing only your data type (SurfaceLightTrait.cs in the above example) into the Assets/MARS/Extension Types folder. A recompile will happen, and then your trait type is ready to use.

    If you've already written a Condition or Relation that uses your data type, but it's not in the extension types folder, MARS will detect this and log a message in the console reminding you to move the data type's file.

    Back to top
    Terms of use
    Copyright © 2023 Unity Technologies — Terms of use
    • Legal
    • Privacy Policy
    • Cookies
    • Do Not Sell or Share My Personal Information
    • Your Privacy Choices (Cookie Settings)
    "Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
    Generated by DocFX on 18 October 2023