【UIToolkit】PointerManipulatorでUI上マウスの動きを取得する

# 概要
ドラッグ&ドロップなど、マウスの状態を取得したい場合があります
その時に役立つのがPointerManipulatorです

PointerManipulatorはabstractクラスで、継承して以下のように使われます

```csharp:PointerHandler.cs
public class PointerHandler : PointerManipulator
{
    public PointerHandler(VisualElement target)
    {
        this.target = target;
    }

    protected override void RegisterCallbacksOnTarget()
    {
        target.RegisterCallback<PointerDownEvent>((_) => { Debug.Log("OnPointerDownEvent"); });
        target.RegisterCallback<PointerMoveEvent>((_) => { Debug.Log("OnPointerMoveEvent"); });
        target.RegisterCallback<PointerUpEvent>((_) => { Debug.Log("OnPointerUpEvent"); });
        target.RegisterCallback<PointerOverEvent>((_) => { Debug.Log("PointerOverEvent"); });
        target.RegisterCallback<PointerOutEvent>((_) => { Debug.Log("PointerOutEvent"); });
        target.RegisterCallback<PointerEnterEvent>((_) => { Debug.Log("PointerEnterEvent"); });
        target.RegisterCallback<PointerLeaveEvent>((_) => { Debug.Log("PointerLeaveEvent"); });
    }

    protected override void UnregisterCallbacksFromTarget()
    {
        target.UnregisterCallback<PointerDownEvent>((_) => { Debug.Log("OnPointerDownEvent"); });
        target.UnregisterCallback<PointerMoveEvent>((_) => { Debug.Log("OnPointerMoveEvent"); });
        target.UnregisterCallback<PointerUpEvent>((_) => { Debug.Log("OnPointerUpEvent"); });
        target.UnregisterCallback<PointerOverEvent>((_) => { Debug.Log("PointerOverEvent"); });
        target.UnregisterCallback<PointerOutEvent>((_) => { Debug.Log("PointerOutEvent"); });
        target.UnregisterCallback<PointerEnterEvent>((_) => { Debug.Log("PointerEnterEvent"); });
        target.UnregisterCallback<PointerLeaveEvent>((_) => { Debug.Log("PointerLeaveEvent"); });

    }
}
```

このPointerManipulatorを適当な場所でインスタンス化します
```csharp
public class PointTestPanel : EditorWindow
{
    [SerializeField]
    private VisualTreeAsset m_VisualTreeAsset = default;

    [MenuItem("Window/UI Toolkit/PointTestPanel")]
    public static void ShowExample()
    {
        PointTestPanel wnd = GetWindow<PointTestPanel>();
        wnd.titleContent = new GUIContent("PointTestPanel");
    }

    public void CreateGUI()
    {
        VisualElement root = rootVisualElement;
        m_VisualTreeAsset.CloneTree(root);

        var pointerTarget = root.Q("pointerTarget");
        _ = new PointerHandler(pointerTarget);
    }
}
```

上記のようにイベントを登録すると、UI上の要素に対してマウスなどのPointerがイベントを発火するようになります

# イベント一覧
### PointerDownEvent
https://docs.unity3d.com/6000.0/Documentation/ScriptReference/UIElements.PointerDownEvent.html

要素が押された時に発火します

### PointerMoveEvent
https://docs.unity3d.com/6000.0/Documentation/ScriptReference/UIElements.PointerMoveEvent.html

Pointerの状態が変化したときに発火します
動いた時にだけ発火するわけではなく、トラックパットの圧力が変化したり、2つ目のマウスボタンが押された時なども発火することに注意が必要です

### OnPointerUpEvent
https://docs.unity3d.com/6000.0/Documentation/ScriptReference/UIElements.PointerUpEvent.html

ボタンが離されて時に発火します

### PointerOutEvent
https://docs.unity3d.com/6000.0/Documentation/ScriptReference/UIElements.PointerOutEvent.html

targetとなった要素と、その子要素から出た時に発火されます
子要素がある場合、それらを出たタイミングで逐一発火します

![スクリーンショット 2024-12-24 2.29.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100503/7be7f5f3-4657-1bc6-d289-9ca8223a7d1b.png)

画像のようにマウスが移動した場合、黒を出たタイミングと青を出たタイミングの2回発火されます

### PointerLeaveEvent
https://docs.unity3d.com/6000.0/Documentation/ScriptReference/UIElements.PointerLeaveEvent.html

targetとなった要素と、その子要素<b>全て</b>から出た時に発火されます
PointerOutEventと似ていますが、基本的にこれを使えば間違いないです

### PointerOverEvent
https://docs.unity3d.com/6000.0/Documentation/ScriptReference/UIElements.PointerOverEvent.html

Pointerが要素かその子に入った時に発火します

![スクリーンショット 2024-12-24 2.37.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100503/818dad6f-6bd1-31eb-dd2b-087cf9c4baf6.png)

例えば上画像のようにマウスを動かした時、黒に入った時と青に入った時の２回発火します

### PointerEnterEvent
https://docs.unity3d.com/6000.0/Documentation/ScriptReference/UIElements.PointerEnterEvent.html

Pointerが要素かその子に入った時に発火します

![スクリーンショット 2024-12-24 2.37.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100503/818dad6f-6bd1-31eb-dd2b-087cf9c4baf6.png)

例えば上画像のようにマウスを動かした時、黒に入った時の１回しか発火しません

# その他
マニュアルのドラッグ実装サンプルにも使われているので参考にしてみてください

https://docs.unity3d.com/6000.0/Documentation/Manual/UIE-create-drag-and-drop-ui.html