Version: Unity 6.7 Alpha (6000.7)
Language : English
Persistent variables source
String source

Properties source

Read a member by name from the current value through the Unity.Properties data model.

The Properties source evaluates a named selector against the current object with Unity.Properties, the same data model that UI Toolkit data binding uses. It matches the selector to a member that Unity.Properties exposes and returns its value. It works with plain classes and structs, as well as MonoBehaviour fields, without registering a property bag in advance.

The Properties source is the default way members are read by name. It resolves the members that Unity.Properties exposes. When a selector does not match an exposed member, the source returns without a result and any later source in the formatter handles the selector.

When matching, string values are handled by the String source, so the Properties source ignores them.

Member matching is case-sensitive. When the formatter uses case-insensitive matching, a differently cased selector does not resolve through this source.

Use the nullable operator to return an empty result instead of an error when the current value is null, for example ({Address?.City}).

Smart String Argument Result
{Name} reached level {Level}. new PlayerData { Name = "Juan Pérez", Level = 12 } Juan Pérez reached level 12.
var player = new PlayerData { Name = "Juan Pérez", Level = 12 };

// "Juan Pérez reached level 12."
Smart.Format("{Name} reached level {Level}.", player);
class Enemy
{
    // A public field is visible with no attribute.
    public string Name = "Goblin";

    // A private field is visible when you mark it with [SerializeField].
    [SerializeField]
    int m_Health = 30;

    // A plain, non-attributed property is not visible.
    public int Score => 100;
}
var enemy = new Enemy();

// "Goblin has 30 health." m_Health resolves through [SerializeField].
Smart.Format("{Name} has {m_Health} health.", enemy);

Mark members so the Properties source can read them

The members the Properties source exposes follow Unity’s serialization rules:

  • Public fields.
  • Private or internal fields marked with [SerializeField].
  • Members marked with [CreateProperty] or [SerializeReference].

This includes non-public members that carry those attributes. Methods and plain, non-attributed properties are not exposed and do not resolve through this source. To read those, write a custom source.

class Enemy
{
    // A public field is visible with no attribute.
    public string Name = "Goblin";

    // A private field is visible when you mark it with [SerializeField].
    [SerializeField]
    int m_Health = 30;

    // A plain, non-attributed property is not visible.
    public int Score => 100;
}
var enemy = new Enemy();

// "Goblin has 30 health." m_Health resolves through [SerializeField].
Smart.Format("{Name} has {m_Health} health.", enemy);

Generate property bags to avoid reflection

By default, Unity.Properties builds a property bag for a type through reflection the first time it reads that type. To avoid the reflection, mark the type with [GeneratePropertyBag] and opt the assembly in with [assembly: GeneratePropertyBagsForAssembly]. The source generator then emits the property bag at compile time. This improves performance and is important on fully ahead-of-time compiled players, where the reflection fallback is limited.

[GeneratePropertyBag]
public partial class Character
{
    public string Name;
}

Additional resources

Persistent variables source
String source