Version: 2023.1
言語: 日本語
C# スクリプトから UXML をインスタンス化する
C# スクリプトによる UI の構築

UQuery でビジュアル要素を検索する

UQuery を使用すると、ビジュアルツリー から要素を見つけることができます。UQuery は JQuery と Linq に発想を得て、動的なメモリ割り当てを制限するように設計されています。これにより、モバイルプラットフォームで最適なパフォーマンスを実現できます。

クエリメソッド

UQuery は以下の拡張メソッドを介して使用できます。

内部的には、Q メソッドと Query メソッドは UQueryBuilder を使用し、クエリを作成します。これらの拡張メソッドは、UQueryBuilder を作成する際の煩雑さを軽減します。

UQuery を使用して要素を検索するには、まず UXML を ロード して インスタンス化 し、それから Query または Q を使用してルートのビジュアル要素に選択ルールを作成する必要があります。

Query は選択ルールに一致する要素のリストを返します。FirstLastAtIndexChildrenWhere など、UQueryBuilder のパブリックメソッドを使用して、Query の返り値にフィルターをかけることができます。

QQuery<T>.First()の省略形です。選択規則に一致する最初の要素を返します。

クエリー要素

要素の 名前USS クラス要素の型 (C# 型) でクエリを実行できます。また、述語 を使ったクエリや 複雑な階層クエリ の作成も可能です。

以下のセクションでは、この例の UXML を使用して、要素の検索方法を説明します。

<UXML xmlns="UnityEngine.UIElements">
    <VisualElement name="container1">
      <Button name="OK" text="OK" />
      <Button name="Cancel" text="Cancel" />
    </VisualElement>
     <VisualElement name="container2">
      <Button name="OK" class="yellow" text="OK" />
      <Button name="Cancel" text="Cancel" />
    </VisualElement>
    <VisualElement name="container3">
      <Button name="OK" class="yellow" text="OK" />
      <Button name="Cancel" class="yellow" text="Cancel" />
    </VisualElement>
</UXML>

名前によるクエリ

要素を name (名前) で検索するには、Query(name: "element-name")Q(name: "element-name") を使用します。name は最初の引数なので省略できます。

下の例は、“Ok” という名前の要素を見つけます。

List<VisualElement> result = root.Query("OK").ToList();

下の例では、Query を使って “Ok” という名の最初の要素を見つけます。

VisualElement result = root.Query("OK").First(); //or VisualElement result = root.Q("OK");

下の例では、Qを使って“Ok ”という最初の要素を見つけます。

VisualElement result = root.Q("OK");

下の例は、“Ok” という名前の 2 番目の要素を見つます。

VisualElement result3 = root.Query("OK").AtIndex(1);

下の例は、“Ok” という名前の最後の要素を見つます。

VisualElement result4 = root.Query("OK").Last();

USS クラスによるクエリ

USS クラスで 要素を検索するには、Query(className: "class-name")Q(className: "class-name") を使用します。

下の例では、クラス “yellow” を持つすべての要素を見つけ、それらをリストに割り当てます。

List<VisualElement> result = root.Query(className: "yellow").ToList();

下の例では、クラス “yellow” を持つ最初の要素を見つけます。

VisualElement result = root.Q(className: "yellow");

要素の型によるクエリ

要素の型 (C# 型) から要素を検索するには、Query<Type>Q<Type> を使用します。

下の例では最初のボタンを見つけ、それにツールチップを加えます。

VisualElement result = root.Q<Button>();
result.tooltip = "This is a tooltip!";

下の例では、3 つ目のボタンを見つけます。

VisualElement result = root.Query<Button>().AtIndex(2);

ノート: 基本クラスではなく、要素の実際の型によってのみクエリを行うことができます。

述語によるクエリ

名前、クラス、型で要素を問い合わせる以外に、Where メソッドを使用して、述語を満たすすべての要素を選択することもできます。述語は、単一の VisualElement 引数をとる関数コールバックでなければなりません。

下の例は、ツールチップを持たない “yellow” USS クラスを持つすべての要素を見つけます。

List<VisualElement> result = root.Query(className: "yellow").Where(elem => elem.tooltip == "").ToList();

複雑な階層クエリ

name、class、type を組み合わせて、複雑な階層クエリを作ることができます。

下の例では、クラス “yellow” を持つ “OK” という名の最初のボタンを見つけます。

VisualElement result = root.Query<Button>(className: "yellow", name: "OK").First();

下の例では、 “container2” の子キャンセルボタンを見つけます。

VisualElement result = root.Query<VisualElement>("container2").Children<Button>("Cancel").First();

結果の操作

ForEach メソッドを使用すると、クエリ結果を直接操作できます。

下の例では、ツールチップのない要素にツールチップを加えます。

root.Query().Where(elem => elem.tooltip == "").ForEach(elem => elem.tooltip="This is a tooltip!");

ベストプラクティス

UQuery を使用する際は、以下の点を考慮してください。

  • UQuery は、名前、クラス、型によって要素を見つけるために階層を走査します。初期化時に UQuery の結果をキャッシュします。
  • 複数の要素を取得する必要がある場合は、QueryState 構造体 (element.Query() メソッドで返されます) を使用し、リストの作成を避けるために列挙します。また、クエリを一度構築し、異なる要素に対して実行することもできます。
  • UI Toolkit は、不要になったビジュアル要素を破棄しません。C# のガベージコレクターを使用して収集します。要素の取得元の UIDocuments または Window よりも長く存続するクラスのビジュアル要素への参照を誤って保持しないように注意してください。
  • クロージャ内に VisualElement 変数をキャプチャします。
  • たくさんの要素を作成またはリリースする場合は、ガベージコレクターのスパイクを避けるために、増分ガベージコレクション を有効にします。

その他の参考資料

C# スクリプトから UXML をインスタンス化する
C# スクリプトによる UI の構築