【Unity】画面サイズと異なる大きさの RenderTexture でクリック位置の WorldPoint が取りたい話
はじめに
Unity では基本的に、 uGUI などの GUI はカメラを使って表示する 3D より手前に表示されます。
ただ、例えばポップアップウインドウのような表示がしたいなど、 GUI より手前に 3D を表示したい場合もあります。
それを解決する方法として RenderTexture を使う方法があります(正しい方法かどうかは不明)。
が、それを使って表示した内容に対してクリックし、その位置を 3D(WorldPoint) に変換しようとしたらうまくいかなかったのでメモです。
準備
- 画面サイズは 1920 * 1200 とします。
- RenderTexture のサイズは 1100 * 600 とします。
- Canvas を下記の内容で準備します。
- Canvas Scaler の UI Scale Mode を Scale with Screen Size にし、Reference Resolution を 1920 * 1200 とします。
- Raw Image を追加し、サイズを 1100 * 600 に設定します。
- 2.の Anchors を X = 0, Y = 1 に設定します。
- RenderTexture のサイズを 1100 * 600 で作成し、2.の Texture にアタッチします。
- 今回は特定の位置に置いた Plane 上のクリック位置を取ります。
- カメラの正面に Plane を適当なサイズに置きます(カメラから Z 方向に 10 離す)。
- クリック位置が分かりやすいように、適当なサイズの Cube を置きます。
(初期位置はどこでも良いです)
クリック位置を取ってみる
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MainController : MonoBehaviour {
public Camera MainCamera;
// RenderTexture
public RectTransform TextureTransform;
// クリック位置上に置く Cube.
public Transform ClickTransform;
// Plane
public Transform PlaneTransform;
private Vector2 texturePosition;
private Vector2 screenScale;
private Vector3 screenInputPosition = Vector3.zero;
private void Start () {
// 実行中の画面サイズを 1920 * 1200 にスケーリング.
screenScale = new Vector2(
Screen.width / 1920f,
Screen.height / 1200f);
// 今回は RenderTexture の位置が動的に変わらないものとする.
texturePosition = TextureTransform.position;
}
private void Update () {
if(Input.GetMouseButtonUp(0)) {
// クリック位置が RenderTexture でのどの位置にあるかを算出.
// 座標値は画面サイズ 1920 * 1200 での値を使う必要がある.
screenInputPosition.x = (Input.mousePosition.x - texturePosition.x) / screenScale.x;
screenInputPosition.y = ((Input.mousePosition.y - texturePosition.y) / screenScale.y) +
TextureTransform.sizeDelta.y;
// クリック位置を取りたい Plane と カメラの Z 軸の差分を入れることで、 Plane 上の座標値に変換できる.
screenInputPosition.z = PlaneTransform.localPosition.z - MainCamera.transform.localPosition.z;
ClickTransform.position = MainCamera.ScreenToWorldPoint(screenInputPosition);
}
}
}
注意点としては、 2D の Y 座標は画面上部が 0 、3D は下が 0 になる、というところと、 ScreenToWorldPoint に渡す座標は画面サイズが 1920 * 1200 であったときのものに合わせる必要がある、ということです。