Unity UI Toolkit での座標変換

初めに

UI Toolkit での座標変換が分かりづらかったのでまとめました。

修正:2025/08/12 一部の関数で、引数が Vector3 になっていたのを Vector2 に変更

参考

https://discussions.unity.com/t/is-there-runtimepanelutils-paneltoscreen/911004/6

https://light11.hatenadiary.com/entry/2023/05/10/190035

サンプルコード


using UnityEngine;
using UnityEngine.UIElements;

namespace Assets.Scripts
{
    internal static class Extensions
    {
        public static Vector2 PanelWorldToScreen(this IPanel panel, Vector2 panelWorldPos)
        {
            var min = RuntimePanelUtils.ScreenToPanel(panel, Vector2.zero);
            var max = RuntimePanelUtils.ScreenToPanel(panel, new(Screen.width, Screen.height));

            float screenX = Screen.width * (panelWorldPos.x - min.x) / (max.x - min.x);
            float screenY = Screen.height * (1f - (panelWorldPos.y - min.y) / (max.y - min.y));

            return new(screenX, screenY);
        }

        public static Vector2 PanelWorldToScreen(this VisualElement ve, Vector2 panelWorldPos)
        {
            return ve.panel.PanelWorldToScreen(panelWorldPos);
        }

        public static Vector2 ScreenToPanelWorld(this IPanel panel, Vector2 screenPos)
        {
            screenPos.y = Screen.height - screenPos.y;
            return RuntimePanelUtils.ScreenToPanel(panel, screenPos);
        }

        public static Vector2 ScreenToPanelWorld(this VisualElement ve, Vector2 screenPos)
        {
            return ve.panel.ScreenToPanelWorld(screenPos);
        }

        public static Vector2 PanelWorldToPanelLocal(this VisualElement ve, Vector2 panelWorldPos)
        {
            return ve.WorldToLocal(panelWorldPos);
        }

        public static Vector2 PanelLocalToPanelWorld(this VisualElement ve, Vector2 panelLocalPos)
        {
            return ve.LocalToWorld(panelLocalPos);
        }

        public static Vector2 ScreenToPanelLocal(this VisualElement ve, Vector2 screenPos)
        {
            var panelWorldPos = ve.ScreenToPanelWorld(screenPos);
            return ve.PanelWorldToPanelLocal(panelWorldPos);
        }

        public static Vector2 PanelLocalToScreen(this VisualElement ve, Vector2 panelLocalPos)
        {
            var panelWorldPos = ve.PanelLocalToPanelWorld(panelLocalPos);
            return ve.PanelWorldToScreen(panelWorldPos);
        }

        public static Vector3 PanelWorldToWorld(this Camera camera, IPanel panel, Vector2 panelWorldPos)
        {
            Vector2 screenPos = panel.PanelWorldToScreen(panelWorldPos);
            return camera.ScreenToWorldPoint(screenPos);
        }

        public static Vector3 PanelWorldToWorld(this Camera camera, VisualElement ve, Vector2 panelWorldPos)
        {
            return camera.PanelWorldToWorld(ve.panel, panelWorldPos);
        }

        public static Vector2 WorldToPanelWorld(this Camera camera, IPanel panel, Vector3 worldPos)
        {
            Vector2 screenPos = camera.WorldToScreenPoint(worldPos);
            return panel.ScreenToPanelWorld(screenPos);
        }

        public static Vector2 WorldToPanelWorld(this Camera camera, VisualElement ve, Vector3 worldPos)
        {
            return camera.WorldToPanelWorld(ve.panel, worldPos);
        }

        public static Vector3 PanelLocalToWorld(this Camera camera, VisualElement ve, Vector2 palenLocalPos)
        {
            var panelWorldPos = ve.PanelLocalToPanelWorld(palenLocalPos);
            return camera.PanelWorldToWorld(ve, panelWorldPos);
        }

        public static Vector2 WorldToPanelLocal(this Camera camera, VisualElement ve, Vector3 worldPos)
        {
            var panelWorldPos = camera.WorldToPanelWorld(ve, worldPos);
            return ve.PanelWorldToPanelLocal(panelWorldPos);
        }
    }
}

top

その他の投稿
20250812-02 Unity UI Toolkit でのタップ操作検出
20250812-01 Unity UI Toolkit でマップ画面 with RenderTexture
20250721-01 Unityでカメラが平行投影の場合にScreenToWorldPointがズレる
20250712-01 Unity既存プロジェクトにURP追加
20250320-01 Unity のナビゲーションシステム 追記
20241013-01 Google Play で開発者情報が公開される件
20240824-01 Unity UI Toolkit カスタムコントロールサンプル
20240720-01 Unity NavMesh サンプル
20240529-02 Unity ECS の Android ビルドでエラー
20240529-01 Unity ECS で、Prefab を使用した場合に Android ビルドでエラー