エイリアンプログラム

主にゲームプログラミングに関するブログです。

RectTransformからワールド座標に変換する方法

さてさて、今回はRectTransform(uGUI)からワールド座標に変換する方法を投稿しようと思います。
昔、私がUnityを始めた頃はnGUIが盛んでしたが、時が経つにつれて今ではuGUIが主流となってきました(まあ、作った人は同一人物らしいですが…)。

細かい説明を省きますが、通常uGUI(Canvasと記す)の座標とワールド座標は全くの別物です。
例えば、Canvas内のImage(以下の画像の①)の座標が(-39.1, 5.72, 0)だとして、ワールド座標であるGameObjectの座標(以下の画像の②)に(-39.1, 5.72, 0)を代入しても、ImageとGameObjectは重なりません。 f:id:alien_program:20170806155743p:plain

そこで以下の処理を行うことで、ImageとGameObjectを重ねることが出来ます。

private Vector3 GetWorldPositionFromRectPosition(RectTransform rect)
{
//UI座標からスクリーン座標に変換
Vector2 screenPos = RectTransformUtility.WorldToScreenPoint(m_canvas.worldCamera, rect.position);

//ワールド座標
Vector3 result = Vector3.zero;

//スクリーン座標→ワールド座標に変換
RectTransformUtility.ScreenPointToWorldPointInRectangle(rect, screenPos, m_canvas.worldCamera, out result);

return result;
}

上記で行った内容は以下の通りです。
1. RectTransformUtility.WorldToScreenPointで、UIの座標をスクリーン座標に変換する。
2. 1で取得したスクリーン座標を、RectTransformUtility.ScreenPointToWorldPointInRectangleを使ってワールド座標に変換(result)する。

結果は以下の通りになります。
* 左の画像:赤色のImageの座標をワールド座標に算出して、GameObjectの座標にそれを代入した状態
* 右の画像:青色のImageの座標をワールド座標に算出して、GameObjectの座標にそれを代入した状態
f:id:alien_program:20170806160613p:plain

※捕捉

RectTransformUtility.WorldToScreenPoint
第一引数:UIのカメラ。今回はCanvasで設定したRenderCameraを代入(RenderModeをScreenSpace Cameraに設定)
第二引数:スクリーン座標に変換したいUIのRectTransformを代入

f:id:alien_program:20170806152547p:plain

RectTransformUtility.ScreenPointToWorldPointInRectangle
第一引数:指定のUIのRectTransformを代入
第二引数:指定のUIのスクリーン座標を代入
第三引数:Canvasで使用しているCameraを代入
第四引数:取得したワールド座標の結果(参照渡し)


以上となります。
正直細かい説明は端折ましたが、これを使用することによって指定のGameObjectを指定のUIのところに移動させることが可能になりました。