UnityのUI ToolkitのVisualElement.transformでUIアニメーションを実装する方法についてまとめました。
Unity 2022.2.17
Transformとは?
UI Toolkitにおいては、Flexboxの概念に沿ったレイアウトシステムにより各Visual Elementの座標やサイズが自動計算されます。
UI BuilderではPositionやFlex、Sizeなどの項目によりこのレイアウトの設定を行うことができます。
これとは別に、Transformという項目があります。
これを設定するとVisual Elementを移動・スケーリング・回転、またその起点を設定することができます。
さてこのTransformによる変形は、Flexboxベースの自動レイアウトが行われた後に処理されます。
すなわち、自動レイアウトで決定された他のVisual Elementの座標などには影響しない形で、対象のVisual Elementだけを変形することができます。
また、レイアウトが再計算されないため処理負荷も軽いです。
これらの特性から、UIアニメーションを作る際にはこのTransformが有用です。
本記事ではこのTransformを使って簡単なUIアニメーションを実装してみます。
UI Builderで初期値を設定する
それではアニメーションを行う準備として、まずUI Builderでレイアウトを組んでTransformの項目に初期値を設定します。
今回は下図のように、緑のVisual ElementのTransformを(100, 50)に設定して移動させ、回転の起点となるOriginを左上に設定しました。
なおこれらのプロパティはUSSで設定することもできます。
詳細は本記事では割愛しますが、以下のドキュメントに詳しく書かれているので必要に応じて参照してください。
スクリプトでアニメーションさせる
次にスクリプトを使ってこれをアニメーションさせます。
スクリプトによりTransformによる変形を行うには、以下のようにVisualElement.transform
を書き換えます。
using System.Threading.Tasks; using UnityEditor; using UnityEngine; using UnityEngine.UIElements; public sealed class Example : EditorWindow { private const int DeltaTimeMillis = (int)(1.0f / 60.0f * 1000); [SerializeField] private VisualTreeAsset visualTree; private void CreateGUI() { visualTree.CloneTree(rootVisualElement); var green = rootVisualElement.Q<VisualElement>("Green"); // アニメーションを開始 var _ = RotateGreenAsync(green); } private static async Task RotateGreenAsync(VisualElement target) { while (true) { await Task.Delay(DeltaTimeMillis); // VisualElement.transformを使って回転させる target.transform.rotation *= Quaternion.Euler(Vector3.forward * 10.0f); } } [MenuItem("Window/Example")] public static void ShowWindow() { GetWindow<Example>(); } }
このスクリプトのInspectorから前節のUXMLをアサインし、実行すると下図の結果が得られます。
正常にアニメーションしていることを確認できました。
localBoundとworldBoundとTransform
VisualElementにはlocalBound
とworldBound
というプロパティがあります。
これはそれぞれ名前の通り、ローカル空間とワールド空間(EditorWindowだったらウィンドウ基準の空間)の座標情報を表します。
ただし、localBound
はTransformを適用する前の情報であるのに対し、worldBound
はTransformを適用した後の情報になります。
これらを使う際にはこの点に注意が必要です。