【Unity】uGUIでCanvasのRender Modeによってローカル座標への変換方法が異なる件

  • 41
    Like
  • 3
    Comment
More than 1 year has passed since last update.

Unity4.6から導入されたuGUIはなかなかベンリなもので、さくっとGUIが作れる。
今回は、そのuGUIのRender Modeによる座標系への影響に関するお話。

Render Modeについて

CanvasのRender Modeは、デフォルトで「Screen Space - Overlay」となっている。
これはCanvasをオーバーレイ表示するモードで、普通に使う分にはこの状態で全然問題なっしんぐ。

しかし、uGUIとパーティクルを併用しようとすると、オーバーレイではパーティクルに被せてGUIを描画してしまうので、パーティクルが表示されない。

そういうときはRender Modeを「Screen Space - Camera」に変えて、CanvasのRender Cameraにメインカメラを紐付ければOK。
オーバーレイ表示とは違って、メインカメラに写して描画させるイメージですな。

Render Modeに応じたローカル座標系への変換方法

で、本題。

「Screen Space - Camera」に変えてもほとんどの機能は問題無く使える。
ただし、IDragHandler等でクリック位置の座標を得て、ローカル座標に変換しようとする場合には注意が必要。

例えば、下記のような形でドラッグ可能なGUI要素を作るとする。
この際、Render Modeに応じてローカル座標への変換方法が異なる。

C#
public class Hoge : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler
{
    ...略...

    public void OnDrag(PointerEventData ped)
    {
        // TODO ここでped.positionをthisのローカル座標に変換して使いたい
    }

    ...略...
}

1.「Screen Space - Overlay」の場合
「Screen Space - Overlay」だと、PointerEventDataのローカル座標変換は下記の形でOK。

C#
var localPos = transform.InverseTransformPoint(ped.position);

2.「Screen Space - Camera」の場合
「Screen Space - Camera」では下記の方法でローカル座標に変換する。

C#
Vector2 localPos = Vector2.zero;
RectTransformUtility.ScreenPointToLocalPointInRectangle(GetComponent<RectTransform>(), ped.position, Camera.main, out localPos);

「World Space」は試してないけど、RectTransformUtilityにそれっぽいメソッドがあったので、そのへん使えば出来るかも。

覚える事は結構あるけども、uGUIホント使えますなぁ。