ロバメモ - 素人のUnity覚書と奮闘記

素人のUnity覚書と奮闘記

CanvasのGameObjectをmousePositionに追従させたい

あんまり自信ないかも。
いや、自信満々で書いた記事などないけど。笑

やりたいこと

お題通り、キャンバスに配置した画像をカーソル追従させたい。

やり方

以下のコードを追従させたいゲームオブジェクトにアタッチする。

    RectTransform canvasRect;

    private void Awake()
    {
        canvasRect = GameObject.Find("Canvas").GetComponent<RectTransform>();
    }

    private void Update()
    {
        var mousePos = Input.mousePosition;
        var magnification = canvasRect.sizeDelta.x / Screen.width;
        mousePos.x = mousePos.x * magnification - canvasRect.sizeDelta.x / 2;
        mousePos.y = mousePos.y * magnification - canvasRect.sizeDelta.y / 2;
        mousePos.z = transform.localPosition.z;

        transform.localPosition = mousePos;
    }

考え方

座標の違いを解消する

Input.mousePosition = スクリーン座標
スクリーン座標というのは、実寸って感じかな。実際に表示された画面サイズのピクセル座標を返す。

RectTransform.sizeDelta = キャンバス座標
これは、unityで設定したキャンバスサイズのこと。

つまり、実際のサイズ=キャンバスサイズであれば、1 : 1 になるので、
transform.localPosition = Input.mousePosition;でいけるはず。
でも、端末の画面に合わせたりするはずなので、倍率を計算する必要がある。
それがこの部分。

var magnification = canvasRect.sizeDelta.x / Screen.width;

この倍率を、mousePositionに掛ければ、マウスの位置をキャンバス座標に変換できる。

座標の起点の違いを解消する

マウスの位置をキャンバス座標に変換しても、Input.mousePositionの起点が画面左下なのに対し、キャンバス座標は画面の中心が起点になっている模様。
ということで、起点を揃える必要がある。
倍率をかけてキャンバス座標にして、起点を揃えた部分がこれ。

mousePos.x = mousePos.x * magnification - canvasRect.sizeDelta.x / 2;
mousePos.y = mousePos.y * magnification - canvasRect.sizeDelta.y / 2;
mousePos.z = transform.localPosition.z;

※キャンバス上なので、z座標は固定にしておく。
   以上。