はじめに
RectTransform
のCorners
(角)の座標のスクリーン座標を取得しようと思ったところ少し手間取ったので書き残しておきたいと思います。
私が調べた限りCanvas
のRenderMode
によって動作が異なるようなので、それぞれについて書きます。
また原因が異なる可能性も大いにある(誤った情報を書いてしまった場合は恐縮です)ので、もし間違っている場合はご指摘いただけると嬉しいです。
CanvasのRenderModeが「Screen Space - Overlay」
RectTransformの四隅のワールド座標を取得
RectTransform.GetWorldCorners
メソッドを利用することで、RectTransform
の長方形の角の座標を取得することができます。
docs.unity3d.com
var rectTransform = GetComponent<RectTransform>(); // ワールド空間におけるRectTransformの長方形の角の座標を取得 // 返される4つの頂点は時計回りに「左下,左上,右上,右下」 var corners = new Vector3[4]; rectTransform.GetWorldCorners(corners); for (var i = 0; i < corners.Length; i++) { // 例 // Screen Corners[0] : (1185.0, 418.0, 0.0) // Screen Corners[1] : (1185.0, 918.0, 0.0) // Screen Corners[2] : (1685.0, 918.0, 0.0) // Screen Corners[3] : (1685.0, 418.0, 0.0) Debug.Log($"World Corners[{i}] : {corners[i]}"); }
Canvas
のRenderMode
がScreen Space - Overlay
の場合は、RectTransform.GetWorldCorners
メソッドの返り値がそのままスクリーン座標になっているようでした。
CanvasのRenderModeが「Screen Space - Camera」
RectTransformの四隅のワールド座標を取得
同様にRectTransform.GetWorldCorners
メソッドを利用することで、RectTransform
の長方形の角の座標を取得します。
docs.unity3d.com
var rectTransform = GetComponent<RectTransform>(); // ワールド空間におけるRectTransformの長方形の角の座標を取得 // 返される4つの頂点は時計回りに「左下,左上,右上,右下」 var corners = new Vector3[4]; rectTransform.GetWorldCorners(corners); for (var i = 0; i < corners.Length; i++) { // 例 // World Corners[0] : (0.2, 0.9, -9.0) // World Corners[1] : (0.2, 1.4, -9.0) // World Corners[2] : (0.8, 1.4, -9.0) // World Corners[3] : (0.8, 0.9, -9.0) Debug.Log($"World Corners[{i}] : {corners[i]}"); }
ただこちらで取得できる座標はスクリーン座標にはならないので、加工が必要になります。
(余談)ローカル座標を取得
またRectTransform.GetLocalCorners
メソッドというRectTransform.GetWorldCorners
のローカル座標バージョンもあります。
var rectTransform = GetComponent<RectTransform>(); // ローカル空間におけるRectTransformの長方形の角の座標を取得 // 返される4つの頂点は時計回りに「左下,左上,右上,右下」 var corners = new Vector3[4]; rectTransform.GetLocalCorners(corners); for (var i = 0; i < corners.Length; i++) { // 例 // Local Corners[0] : (-250.0, -250.0, 0.0) // Local Corners[1] : (-250.0, 250.0, 0.0) // Local Corners[2] : (250.0, 250.0, 0.0) // Local Corners[3] : (250.0, -250.0, 0.0) Debug.Log($"Local Corners[{i}] : {corners[i]}"); }
スクリーン座標に変換する
スクリーン座標とは画面の左下を(0, 0)
、右上を(Screen.Width, Screen.Height)
とした座標系のことですね。
RectTransform
の四隅の座標をスクリーン座標で取得するAPI
はないので、ワールド座標からスクリーン座標への変換をしてあげることで解決します。
やり方は簡単で、RectTransformUtility.WorldToScreenPoint
メソッドを利用すればOKです。
docs.unity3d.com
var rectTransform = GetComponent<RectTransform>(); // ローカル空間におけるRectTransformの長方形の角の座標を取得 // 返される4つの頂点は時計回りに「左下,左上,右上,右下」 var corners = new Vector3[4]; rectTransform.GetWorldCorners(corners); for (var i = 0; i < corners.Length; i++) { // ワールド座標からスクリーン座標へ変換 corners[i] = RectTransformUtility.WorldToScreenPoint(Camera.main, corners[i]); // 例 // Screen Corners[0] : (1185.0, 418.0, 0.0) // Screen Corners[1] : (1185.0, 918.0, 0.0) // Screen Corners[2] : (1685.0, 918.0, 0.0) // Screen Corners[3] : (1685.0, 418.0, 0.0) Debug.Log($"Screen Corners[{i}] : {corners[i]}"); }
CanvasのRenderModeが「World Space」
スクリーン座標を取得する
Canvas
のRenderMode
がWorld Space
の場合は、RectTransformUtility.WorldToScreenPoint
を利用します。
var rectTransform = GetComponent<RectTransform>(); // ローカル空間におけるRectTransformの長方形の角の座標を取得 // 返される4つの頂点は時計回りに「左下,左上,右上,右下」 var corners = new Vector3[4]; rectTransform.GetWorldCorners(corners); for (var i = 0; i < corners.Length; i++) { // ワールド座標からスクリーン座標へ変換 corners[i] = RectTransformUtility.WorldToScreenPoint(Camera.main, corners[i]); // 例 // Screen Corners[0] : (1185.0, 418.0, 0.0) // Screen Corners[1] : (1185.0, 918.0, 0.0) // Screen Corners[2] : (1685.0, 918.0, 0.0) // Screen Corners[3] : (1685.0, 418.0, 0.0) Debug.Log($"Screen Corners[{i}] : {corners[i]}"); }