Version: 2019.2
レイアウトエンジン
UXML テンプレートの作成

UXML 形式

UXML ファイルは、ユーザーインターフェースの論理的構造を定義するテキストファイルです。 UXML ファイルで使用される形式は、HTML (HyperText Markup Language)、XAML (eXtensible Application Markup Language)、XML (eXtensible Markup Language) から発想を得ています。これらの良く知られた形式に精通している場合は、UXML に多くの類似点があることに気づくはずです。ただし、UXML 形式には、Unity を効率的に使用するための小さな違いがあります。

This section describes the UXML format that Unity supports and provides details on writing, loading, and defining UXML templates. It also includes information on defining new elements, and how to use UQuery.

UXML makes it is easier for less technical users to build a user interface within Unity. In UXML you can:

  • define the structure of the user interface (UI) in XML.
  • define the UI layout with USS stylesheets.

これにより、開発者はアセットのインポート、ロジックの定義、データの処理などの技術的な作業を行うことができます。

新しい要素の定義

UIElements は拡張可能です。独自のユーザーインターフェースコンポーネントと要素を定義することができます。

Before you can use UXML files to define new elements, you must derive a new class from VisualElement or one of its subclasses, then implement the appropriate functionality within this new class. Your new class must implement a default constructor.

例えば、以下のコードは新しい StatusBar クラスを派生させ、デフォルトのコンストラクターを実装します。

class StatusBar : VisualElement
{
    public StatusBar()
    {
        m_Status = String.Empty;
    }

    string m_Status;
    public string status { get; set; }
}

In order for the UIElements to instantiate a new class when reading a UXML file, you must define a factory for your class. Unless your factory needs to do something special, you can derive the factory from UxmlFactoy<T>. It’s recommended that you put the factory class within your component class.

For example, the following code demonstrates how to define a factory for the StatusBar class by deriving its factory from UxmlFactory<T>. The factory is named UxmlFactory:

class StatusBar : VisualElement
{
    public new class UxmlFactory : UxmlFactory<StatusBar> {}

    // ...
}

With this factory defined, you can use the <StatusBar> element in UXML files.

要素の属性の定義

新しいクラスに UXML の特性 (traits) を定義し、その特性を使用するように Factory を設定することができます。

For example, the following code demonstrates how to define a UXML traits class to initialize the status property as a property of the StatusBar class. The status property is initialized from XML data.

class StatusBar : VisualElement
{
    public new class UxmlFactory : UxmlFactory<StatusBar, UxmlTraits> {}

    public new class UxmlTraits : VisualElement.UxmlTraits
    {
        UxmlStringAttributeDescription m_Status = new UxmlStringAttributeDescription { name = "status" };
        
        public override IEnumerable<UxmlChildElementDescription> uxmlChildElementsDescription
        {
            get { yield break; }
        }

        public override void Init(VisualElement ve, IUxmlAttributes bag, CreationContext cc)
        {
            base.Init(ve, bag, cc);
            ((StatusBar)ve).status = m_Status.GetValueFromBag(bag, cc);
        }
    }

    // ...
}

UxmlTraits には 2 つの目的があります。

  • 新しく作成されたオブジェクトを初期化するために Factory で使用されます。

  • 要素に関する情報を取得するためにスキーマの生成処理によって分析されます。この情報は XML スキーマディレクティブに変換されます。

上のサンプルコードは以下の処理を行います。

  • m_Status の宣言は XML 属性 status を定義します。
  • The uxmlChildElementsDescription returns an empty IEnumerable which indicates that StatusBar element has no child.
  • Init() メンバーは、XML パーサーからプロパティーバッグの status 属性の値を読み込み、StatusBar.status プロパティーにこの値に設定します。
  • StatusBar クラスの中に UxmlTraits クラスを置くことによって Init() メソッドが StatusBar のプライベートメンバーにアクセスできるようにします。
  • 新しい UxmlTraits クラスは基本クラス UxmlTraits を継承しているので、基本クラスの属性を共有します。
  • Init()base.Init() を呼び出して基本クラスのプロパティーを初期化します。

前述のコード例は UxmlStringAttributeDescriptionクラスで文字列属性を宣言しています。UIElements は以下のタイプの属性をサポートし、それぞれが C# 型を XML 型にリンクします。

属性 Attribute value
UxmlStringAttributeDescription A string
UxmlFloatAttributeDescription A single precision floating point value in the range of the C# float type.
UxmlDoubleAttributeDescription A double precision floating point value in the range of the C# double type.
UxmlIntAttributeDescription An integer value in the range of the C# int type.
UxmlLongAttributeDescription A long integer value in the range of the C# long type.
UxmlBoolAttributeDescription true or false
UxmlColorAttributeDescription A string representing a color (#FFFFFF)
UxmlEnumAttributeDescription<T> A string representing one of the values for the Enum type T.

上記のコード例では、uxmlChildElementsDescriptionStatusBar 要素が子を受け付けないことを示す空の IEnumerable を返します。

To have an element accept children of any type, you must override the uxmlChildElementsDescription property. For example, for the StatusBar element to accept children of any type, the uxmlChildElementsDescription property must be specified as follows:

public override IEnumerable<UxmlChildElementDescription> uxmlChildElementsDescription
{
    get
    {
        yield return new UxmlChildElementDescription(typeof(VisualElement));
    }
}

名前空間プレフィックスの定義

C# で新しい要素を定義したら、要素を UXML ファイルで使用することができます。新しい要素が新しい名前空間で定義されている場合は、名前空間のプレフィックスを定義する必要があります。名前空間のプレフィックスはルートの <UXML> 要素への属性として宣言され、要素をスコープするときに完全な名前空間名を置き換えます。

名前空間プレフィックスを定義するには、定義したいそれぞれの名前空間プレフィックスのアセンブリに UxmlNamespacePrefix 属性を加えます。

[assembly:UxmlNamespacePrefix( "My.First.Namespace"、 "first")]
[assembly:UxmlNamespacePrefix( "My.Second.Namespace"、 "second")]

これは、アセンブリの C# ファイルのルートレベル (任意の名前空間の外側) で行います。

スキーマ生成システムは以下を行います。

  • これらの属性をチェックし、それらを使用してスキーマを生成します。
  • 新しく作成された UXML ファイルの <UXML> 要素の属性として名前空間プレフィックスの定義を加えます。
  • xsi:schemaLocation 属性に名前空間のスキーマファイルの場所を含めます。

You should update the UXML schema of your project. Select Assets > Update UIElements Schema to ensure that your text editor recognizes the new element.

The defined prefix is available in the newly created UXML by selecting Create > UIElements Editor Window in the Project/Assets/Editor folder.

より高度な使い方

UXML 名をカスタマイズする

You can customize a UXML name by overriding its IUxmlFactory.uxmlName and IUXmlFactory.uxmlQualifiedName properties. Make sure the uxmlName is unique within your namespace and that the uxmlQualifiedName is unique in your project.

両方の名前が一意でない場合は、アセンブリをロードしようとすると例外がスローされます。

次のサンプルコードは、UXML 名をオーバーライドしてカスタム化する方法を示しています。

public class FactoryWithCustomName : UxmlFactory<..., ...>
{
    public override string uxmlName
    {
        get { return "UniqueName"; }
    }

    public override string uxmlQualifiedName
    {
        get { return uxmlNamespace + "." + uxmlName; }
    }
}

要素の Factory を選択する

デフォルトでは、IUxmlFactory は要素をインスタンス化し、要素の名前を使用して要素を選択します。

IUXmlFactory.AcceptsAttributeBag をオーバーライドすることで、選択プロセスで要素の属性値を考慮させることができます。次に、要素の属性を調べて、UXML 要素のオブジェクトをインスタンス化できるかどうかを決定します。

これは、例えば、VisualElement クラスがジェネリックである場合に便利です。この場合、クラスの特殊化のためのクラス Factory は XML の type 属性の値を調べることができます。値に応じて、インスタンス化を受け入れるか拒否するかを決定します。例は、PropertyControl <T> の実装を参照してください。

複数の Factory が要素をインスタンス化できる場合は、最初に登録された Factory が選択されます。

基本クラス属性のデフォルト値をオーバーライドする

基本クラスで宣言された属性のデフォルト値は UxmlTraits クラスの defaultValue を設定することで変更できます。

For example, the following code shows how to change the default value of m_TabIndex:

class MyElementTraits : VisualElement.UxmlTraits
    {
        public MyElementTraits()
        {
            m_TabIndex.defaultValue = 0;
        }
    }

任意の属性を受け入れる

デフォルトで、XML スキーマが生成されると、要素は任意の属性を持つことができます。

UxmlTraits クラスで宣言されたもの以外の属性の値は制限されません。これは、宣言された属性の値が宣言に一致するかどうかをチェックする XML バリデーターとは対照的です。

追加の属性は IUxmlAttributes の bag に含まれ、IUxmlFactory.AcceptsAttributBag()IUxmlFactory.Init() 関数に渡されます。これらの追加属性を使用するかどうかは、 Factory の実装によって異なります。デフォルトの動作では、追加属性を破棄します。

つまり、これらの追加の属性はインスタンス化された VisualElement にアタッチされず、これらの属性は UQuery でクエリできません。

新しい要素を定義するとき、 UxmlTraits コンストラクターで UxmlTraits.canHaveAnyAttribute プロパティーを false に設定することによって、受け入れられた属性を明示的に宣言された属性に限定することができます。

スキーマ定義の使用

スキーマ定義ファイルは、属性と、各 UXML 要素が含むことのできる属性の子要素を指定します。正しいドキュメントを作成して、ドキュメントを検証するためのガイドとして、スキーマ定義ファイルを使用します。

UXML テンプレートファイルでは、<UXML> ルート要素の xsi:noNamespaceSchemaLocation 属性と xsi:schemaLocation 属性は、スキーマ定義ファイルがどこにあるかを指定します。

Select Assets > Create > UIElements Editor Window to automatically update your schema definition with the latest information from the VisualElement sub-classes used by your project. To force an update of the UXML schema files, select Assets > Update UIElements Schema.

ノート: テキストエディターの中には xsi:noNamespaceSchemaLocation 属性を認識できないものがあります。テキストエディターがスキーマ定義ファイルを見つけることができない場合は、xsi:schemaLocation 属性も指定する必要があります。


  • 2019–05–23 Page amended
レイアウトエンジン
UXML テンプレートの作成