UXML テンプレートは XML マークアップを使って書かれたテキストファイルで、ユーザーインターフェースの論理的構造を定義します。次のコードサンプルは、ユーザーが選択を行うための簡単なパネルを定義する方法を示しています。
<?xml version="1.0" encoding="utf-8"?>
<engine:UXML
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:engine="UnityEngine.Experimental.UIElements"
xsi:noNamespaceSchemaLocation="../UIElementsSchema/UIElements.xsd"
xsi:schemaLocation="UnityEngine.Experimental.UIElements ../UIElementsSchema/UnityEngine.Experimental.UIElements.xsd">
<engine:Label text="Select something to remove from your suitcase:"/>
<engine:Box>
<engine:Toggle name="boots" label="Boots" value="false" />
<engine:Toggle name="helmet" label="Helmet" value="false" />
<engine:Toggle name="cloak" label="Cloak of invisibility" value="false"/>
</engine:Box>
<engine:Box>
<engine:Button name="cancel" text="Cancel" />
<engine:Button name="ok" text="OK" />
</engine:Box>
</engine:UXML>
ファイルの最初の行は XML 宣言です。宣言は任意ですが、含む場合は、最初の行に配置します。宣言前に他のコンテンツやスペースを置くことはできません。version
属性は必須ですが encoding
は任意です。version
が含まれている場合は、それはファイルの文字エンコードを表す必要があります。
次の行はドキュメントルート <UXML>
を定義します。<UXML>
要素には、名前空間のプレフィックス定義の属性とスキーマ定義ファイルの場所が含まれます。これらの属性は特定の順番で指定することはできません。
UIElements では、各要素は UnityEngine.Experimental.UIElements
か UnityEditor.Experimental.UIElements
名前空間で定義されます。
UnityEngine.Experimental.UIElements
名前空間には、Unity Runtime の一部として定義された要素が含まれています。UnityEditor.Experimental.UIElements
名前空間には、Unity エディターで使用できる要素が含まれています。要素を完全に指定するには、要素の名前空間の前に宣言する必要があります。例えば、UXML テンプレートで Button
要素を使いたい場合は、<UnityEngine.Experimental.UIElements:Button/>
と指定する必要があります。
名前空間をより簡単に指定できるようにするために、名前空間のプレフィックスを定義することができます。例えば、 xmlns:engine="UnityEngine.Experimental.UIElements"
は、engine
プレフィックスを UnityEngine.Experimental.UIElements
と同じものとして定義します。
プレフィックスの短縮形が定義されると、 <engine:Button/>
というテキストは <UnityEngine.Experimental.UIElements:Button/>
と同等です。
独自の要素を定義する場合、これらの要素はおそらく独自の名前空間で定義されます。これらの要素を UXML テンプレートで使用したい場合は、名前空間の定義とスキーマファイルの場所を Unity の名前空間と共に <UXML>
タグに含む必要があります。
Asset/Create/UIElements View
メニューから新しい UXML テンプレートアセットを作成すると、Unity エディターは自動的にこれを行います。
UI の定義は <UXML>
ルートの中にあります。UI 定義は一連のネストになった XML 要素で、それぞれが VisualElement
を表します。
要素名は、インスタンス化する要素の C# クラス名に対応します。ほとんどの要素は属性を持ち、その値は C# の対応するクラスプロパティにマップされます。各要素は親クラスの型の属性を継承し、それ自体の属性の集合を追加することができます。VisualElement
はすべての要素の基本クラスであり、すべての要素に対して以下の属性を提供します。
name
: 要素の識別子。名前は一意である必要があります。picking-mode
: マウスイベントに応答する Position
か、マウスイベントを無視する Ignore
を設定します。focus-index
: タブ使用時にフォーカス順を決定するために使用します。フォーカスリングに関しては イベントのディスパッチ を参照してください。class
: 要素を特徴付ける識別子のスペース区切りのリスト。クラスを使用して要素に視覚的スタイルを割り当てます。クラスを使用して、UQuery の一連の要素を選択することもできます。slot-name
と slot
: スロットは、UXML コンポーネントがインスタンス化されたときに他の視覚的要素を挿入するプレースホルダーとして機能します。以下の スロット を参照してください。tooltip
: マウスオーバーするとツールチップとして表示される文字列。UXML テンプレートの例では、ユーザーインターフェースの視覚的な特性は定義されていません。UI を描画するための次元、フォント、色などのスタイル情報は、USS で書かれたスタイルルールを記した別のファイルで定義する必要があります (スタイルと Unity スタイルシート を参照してください)。
コンポーネントを UXML ファイルで定義するだけでコンポーネントを作成し、他の UXML ファイルの <Template>
と <Instance>
要素を使ってインポートできます。
大規模なユーザーインターフェースを設計する場合、UI の一部を定義するテンプレート UXML ファイルを作成できます。
同じ UI 定義を多くの場所で使用できます。例えば、画像、名前、ラベルを持つ横向きの UI 要素があるとします。UXML テンプレートファイルを作成して、横向きの UI 要素を他の UXML ファイルで再利用することができます。
例えば、ファイル Assets/Portrait.uxml
に Portrait コンポーネントがあるとします。
<?xml version = "1.0" encoding = "utf-8"?>
<engine:UXML ...>
<engine:VisualElement class = "portrait">
<engine:Image name = "portaitImage" image = "a.png"/>
<engine:Label name = "nameLabel" text = "Name"/>
<engine:Label name = "levelLabel" text = "42"/>
</engine:VisualElement>
</engine:UXML>
以下のように Portrait コンポーネントを他の UXML テンプレートに埋め込むことができます。
<?xml version = "1.0" encoding = "utf-8"?>
<engine:UXML ...>
<engine:Template path = "Assets/Portrait.uxml" name = "Portrait">
<engine:VisualElement name = "players">
<engine:Instance template = "Portrait" name = "player1"/>
<engine:Instance template = "Portrait" name = "player2"/>
</engine:VisualElement>
</engine:UXML>
UXML コンポーネントは、コンポーネントのインスタンス化時に要素を挿入するスロットを定義できます。Slot は、UXML コンポーネントがインスタンス化されるときに他の視覚的要素を挿入するプレースホルダーとして機能します。
スロットを定義するには slot-name
属性を使用します。例えば、Window.uxml で定義されたウィンドウコンポーネントは、さらに title
と content
という名前の 2 つのスロットを定義することができます。
<?xml version="1.0" encoding="utf-8"?>
<engine:UXML ...>
<engine:VisualElement>
<engine:VisualElement slot-name="title"/>
<engine:ScrollView slot-name="content"/>
</engine:VisualElement>
</engine:UXML>
さらに、テンプレートはテンプレートファイルをインポートすることによってこのウィンドウを使用し、コンテンツをインスタンス化し、それ自体の要素でスロットを埋め、slot
属性を加えることによって視覚的要素を slot-name
にバインドすることができます。
<?xml version="1.0" encoding="utf-8"?>
<engine:UXML ...>
<engine:Template path="Assets/Window.uxml" name="window"/>
<engine:Instance template="window">
<engine:Label slot="title">
<engine:TextBox slot="content"/>
</engine:Instance>
</Window>
結果の視覚的要素の階層は以下のようになります。
VisualElement
VisualElement slot-name="title"
Label slot="title"
ScrollView slot-name="content"
TextBox slot="content"
上の視覚的要素では、slot="title"
属性を持つ Label
が、slot-name="title"
属性を持つ VisualElement
の子として追加されています。
また、コンポーネントの VisualTreeAsset
から C# のスロットを設定することも可能です。
var slots = new Dictionary<string, VisualElement>();
VisualElement t = visualTreeAsset.CloneTree(slots);
slots["title"].add(new Label());
CloneTree
を呼び出した後、slots
ディクショナリはスロット名のマップを VisualElement
スロットに保持します。これを使用して、視覚的要素をスロットの子として追加できます。