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

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

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

You can use UQuery through the Q and Query extension methods. Internally, the Q and Query methods use UQueryBuilder to construct a query. These extension methods reduce the verbosity of creating a UQueryBuilder.

To use UQuery to find elements, you must load and instantiate the UXML first.

To use Query and Q, construct specified selections rules on a root visual element. Query returns a list of elements that match the selection rules. Q is the shorthand for Query<T>.First(). It returns the first element that matches the selection rules.

You can filter the return results of Query with the public methods of UQueryBuilder, such as First, Last, AtIndex, Children, and Where.

You can query elements by their name, their USS class, or their element type(C# type). You can also query with a predicate or make complex hierarchical queries.

以下のセクションでは、この例の 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>

Query by name

To find elements by their name, use Query(name: "element-name") or Q(name: "element-name"). You can omit name as it’s the first argument. For example:

//Find a list of elements named "Ok".
List<VisualElement> result1 = root.Query("OK").ToList();

//Find the first element named "Ok" and add a tooltip for it.
VisualElement result2 = root.Query("OK").First(); //or VisualElement result = root.Q("OK");         
result.tooltip = "This is a tooltip!";    

//Find the second element named "Ok".
VisualElement result3 = root.Query("OK").AtIndex(1);       

//Find the last element named "Ok".
VisualElement result4 = root.Query("OK").Last();

Query by USS class

To find elements by a USS class, use Query(className: "class-name") or Q(className: "class-name"). For example:

//Find all the elements that have the class "yellow" and assign them to a list.
List<VisualElement> result = root.Query(className: "yellow").ToList();

//Find the first element that has the class "yellow".
VisualElement result = root.Q(className: "yellow");

Query by element type

To find elements by their element type(C# type), use Query<Type> or Q<Type>. For example:

//Find the first button and add a tooltip for it.
VisualElement result = root.Q<Button>();
result.tooltip = "This is a tooltip!";

//Find the third button.
VisualElement result = root.Query<Button>().AtIndex(2);

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

Query with a predicate

Other than to query element by name, class, and type, you can also use the Where method to select all elements that satisfy a predicate. The predicate must be a function callback that takes a single VisualElement argument. For example, the following code snippet finds the all the elements with the “yellow” USS class that have no tool tips:

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

Complex hierarchical queries

You can combine name, class, and type to make complex hierarchical queries. For example:

//Find the first button named "OK" that has a class of "yellow".
VisualElement result = root.Query<Button>(className: "yellow", name: "OK").First();
result.tooltip = "This is a tooltip!";

//Find the child cancel button of the "container2".
VisualElement result = root.Query<VisualElement>("container2").Children<Button>("Cancel").First();

Operate on results

You can use the ForEach method to operate directly on the query results. For example, the following code snippet adds a tool tip for any elements that have no tool tips:

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 の構築