いぬおさんのおもしろ数学実験室

おいしい紅茶でも飲みながら数学、物理、工学、プログラミング、そして読書を楽しみましょう

タップされた位置のスクリーン座標からUl(Panelなど)上の座標を得る

 UI部品のどの辺をタップされたのか調べる方法を書きます。ゲーム画面にPanelを配置しました。写真の薄い赤の部分がPanelです。
f:id:Inuosann:20210526105015p:plain:w150
このPanelのどの辺がタップされたのか、検出したいことがあります。照準のコントロールに使うため、正方形のどの辺を押されたか調べたい、など。左の辺りをタップしたら照準は左へ移動、右上辺りをタップしたら右上に移動する、とかです。
 スクリーン上でタップするとスクリーン座標が得られます。これをUI上の座標に変換しなければなりません

 短いコードで説明します。

Vector2 localPoint = Vector2.zero;
GameObject go = GameObject.Find("DirKeyPanel");
RectTransform rc = go.GetComponent<RectTransform>();
if (Input.touchCount == 1)
{
    Touch t = Input.GetTouch(0);//入力情報を取得
    //スクリーン座標をUI上のローカル座標に変換
    //第3引数にはキャンバスのカメラを入れる。Overlayならnullを入れる
    RectTransformUtility.ScreenPointToLocalPointInRectangle(
                rc, t.position, null, out localPoint);
    if (t.phase == TouchPhase.Began)
    {
        if (rc.rect.xMin < localPoint.x && localPoint.x < rc.rect.xMax
                && rc.rect.yMin < localPoint.y && localPoint.y < rc.rect.yMax)
        {
            Debug.Log(localPoint);
        }
    }
}

今回はスクリーン座標をUI上の座標に変換する方法の説明なので、タップの情報の取得については必要最小限のことだけ書きます。

if (Input.touchCount == 1)

はタップされているのは1ヶ所だけ、を意味します。

Touch t = Input.GetTouch(0);

で t にスクリーンのどこがタップされたか、今タップしたのか、動かしているのか、などの情報が格納されます。
"DirKeyPanel" は赤いPanelの名前です。RectTransform rc にはPanelのサイズその他の情報が入ります。

RectTransformUtility.ScreenPointToLocalPointInRectangle(
                rc, t.position, null, out localPoint);

で localPoint にタップされた位置がUI上の座標で得られます。Vector2 です。UI上の座標はUIの真ん中が原点になっているようです。UI部品にはそれが属するキャンバスがあるはずですが、そのキャンバスの Render Mode(インスペクタで見られます)が Overlay の場合、第3引数はnullです。

 if (t.phase == TouchPhase.Began)

は「今、タップされた!」を意味します。

if (rc.rect.xMin < localPoint.x && localPoint.x < rc.rect.xMax
        && rc.rect.yMin < localPoint.y && localPoint.y < rc.rect.yMax)

でUIの長方形内がタップされたことを判定しています。


このサイトの情報が大変参考になりました。Overlayでないときの説明も分かりやすい動画と一緒に載っています。
【Unity】【uGUI】RectTransformUtilityでスクリーン座標をUIのローカル座標やワールド座標に変換する - LIGHT11


 タップについては、今回は1本指の話(1ヶ所だけタップ)しか書いていません。実践では2本以上のことも多く、そのときどうしたらよいのか、という問題がすぐ起こります。いずれまた。今回は座標変換に限って書きました。

 毎回のことですが、今回も相当悩まされました。ゲームの次回作以降ではかなりラクになると思います……。