コガネブログ

平日更新を目標に Unity や C#、Visual Studio、ReSharper などのゲーム開発アレコレを書いていきます

【Unity】ワールド座標を Screen Space - Camera の Canvas 内のローカル座標に変換する関数

ソースコード

using UnityEngine;

public static class CameraUtils
{
    /// <summary>
    /// ワールド座標を Screen Space - Camera の Canvas 内のローカル座標に変換します
    /// </summary>
    /// <param name="worldCamera">ワールド座標を描画するカメラ</param>
    /// <param name="canvasCamera">Canvas を描画するカメラ</param>
    /// <param name="canvasRectTransform">Canvas の RectTransform</param>
    /// <param name="worldPosition">変換前のワールド座標</param>
    /// <returns>変換後のローカル座標</returns>
    public static Vector3 WorldToScreenSpaceCamera
    (
        Camera        worldCamera,
        Camera        canvasCamera,
        RectTransform canvasRectTransform,
        Vector3       worldPosition
    )
    {
        var screenPoint = RectTransformUtility.WorldToScreenPoint
        (
            cam: worldCamera,
            worldPoint: worldPosition
        );

        RectTransformUtility.ScreenPointToLocalPointInRectangle
        (
            rect: canvasRectTransform,
            screenPoint: screenPoint,
            cam: canvasCamera,
            localPoint: out var localPoint
        );

        return localPoint;
    }
}

使用例

using UnityEngine;
using UnityEngine.UI;

public class Example : MonoBehaviour
{
    public Transform m_cube;
    public Text      m_text;

    private void Update()
    {
        // 注意:position ではなく localPosition に値を設定する必要があります
        m_text.rectTransform.localPosition = CameraUtils.WorldToScreenSpaceCamera
        (
            worldCamera: Camera.main,
            canvasCamera: Camera.main,
            canvasRectTransform: m_text.canvas.GetComponent<RectTransform>(),
            worldPosition: m_cube.position
        );
    }
}

f:id:baba_s:20191002152237g:plain

補足

f:id:baba_s:20191002152921p:plain

正しく使用できない場合は、Canvas の Render Mode が
「Screen Space - Camera」になっているかどうか確認してみてください