【Unity】【UI Toolkit】TransitionEventを使ってUSS Transitionに関連するイベントをハンドリングする

UnityのUI ToolkitのTransitionEventを使ってUSS Transitionに関連するイベントをハンドリングする方法についてまとめました。

TransitionEventとは

TransitionEventを使うとUSS Transitionによるトランジションの状態が変化した時のイベントを制御できます。

使用できるイベントは以下の通りです。

イベント名 説明
TransitionRunEvent プロパティが変わってトランジションが作成された時に呼ばれる
TransitionStartEvent ディレイ期間が終わって実際にアニメーションが始まった時に呼ばれる
TransitionEndEvent トランジションが終了した時に呼ばれる
TransitionCancelEvent トランジション中にまたプロパティが変更されたことにより現在のトランジションがキャンセルされた時に呼ばれる

これらのイベントはプロパティごとに呼ばれる仕様になっています。
つまり、位置とスケールという二つのプロパティが同時に変化する場合にはそれぞれのイベントが2回ずつ呼ばれます。

なおUSS Transitionについては以下の記事にまとめていますので、必要に応じて参照してください。

light11.hatenadiary.com

動作確認

それでは実際にこれらのイベントの挙動を試してみます。
以下の記事で作ったものを流用し、Ballにコールバックを登録します。

light11.hatenadiary.com

EditorWindowのコードのみ、上記の記事から以下のように変更します。

using System;
using UnityEditor;
using UnityEngine;
using UnityEngine.UIElements;

public sealed class ExampleWindow : EditorWindow
{
    // uxml
    [SerializeField] private VisualTreeAsset _layout;

    private void OnEnable()
    {
        _layout.CloneTree(rootVisualElement);
        var background = rootVisualElement.Q("Background");
        var ball = rootVisualElement.Q("Ball");

        background.RegisterCallback<ClickEvent>(evt =>
        {
            var targetPos = evt.localPosition;
            targetPos.x -= ball.layout.width / 2;
            targetPos.y -= ball.layout.height / 2;
            ball.transform.position = targetPos;
        });

        // TransitionEventを登録
        void OnTransitionEventExecute(ITransitionEvent evt)
        {
            Debug.Log($"{evt.GetType().Name}:{Environment.NewLine}" +
                      $" - Property Name: {evt.stylePropertyNames}{Environment.NewLine}" +
                      $" - Elapsed Time: {evt.elapsedTime}");
        }
        ball.RegisterCallback<TransitionRunEvent>(OnTransitionEventExecute);
        ball.RegisterCallback<TransitionStartEvent>(OnTransitionEventExecute);
        ball.RegisterCallback<TransitionEndEvent>(OnTransitionEventExecute);
        ball.RegisterCallback<TransitionCancelEvent>(OnTransitionEventExecute);
    }

    [MenuItem("Window/Example")]
    private static void Open()
    {
        GetWindow<ExampleWindow>();
    }
}

Window > Exampleからウィンドウを開いて適当な場所を何回かクリックすると、Consoleに以下のようなログが出力されます。

ログ出力

正常にTransitionEventが動作していることを確認できました。

関連

light11.hatenadiary.com

light11.hatenadiary.com

参考

docs.unity3d.com