UnityのuGUIで点と点を結ぶ線分を作成する

Canvas - Overlay 限定で点と点の線分を書く3D上のワールドの点とCanvas上の点に線分を表示したかったのでコンポーネントを作成しました。
画像のような線分を表示できるようになります。

Screenshot

コード

UILineコンポーネントは、以下の条件下で機能します。

  • UIのCanvasの設定がOverlayであること
  • 3Dのワールド座標 Transform.position と RectTransform.localPositionの対であること
  • UILineのプロパティlineImageのwidthを小さくすると細い線を描画します。
using UnityEngine;
using UnityEngine.UI;

// only Canvas - Overlay
public class UILine : MonoBehaviour
{
    [SerializeField] private RectTransform canvasRectTransform;
    [SerializeField] private Image lineImage;

    public void Draw(Transform trans3D, RectTransform uiElement)
    {
        if (trans3D == null || uiElement == null)
        {
            return;
        }
        Draw(trans3D.position, uiElement.localPosition)
    }

    public void Draw(Vector3 worldPosition, Vector2 uiElementLocalPos)
    {
        var mainCamera = Camera.main;
        if (lineImage == null || canvasRectTransform == null || mainCamera == null)
        {
            return;
        }

        Vector2 screenPoint = RectTransformUtility.WorldToScreenPoint(mainCamera, worldPosition);
        RectTransformUtility.ScreenPointToLocalPointInRectangle(canvasRectTransform, screenPoint, null, out Vector2 localPoint3D);

        DrawLineBetweenPoints(localPoint3D, uiElementLocalPos);
    }

    public void DrawLineBetweenPoints(Vector2 localPositionA, Vector2 localPositionB)
    {
        Vector2 direction = (localPositionA - localPositionB).normalized;
        float distance = Vector2.Distance(localPositionA, localPositionB);

        lineImage.rectTransform.sizeDelta = new Vector2(distance, lineImage.rectTransform.sizeDelta.y);
        lineImage.rectTransform.pivot = new Vector2(0.5f, 0.5f);
        lineImage.rectTransform.anchoredPosition = (localPositionA + localPositionB) / 2;
        float angle = Mathf.Atan2(direction.y, direction.x) * Mathf.Rad2Deg;
        lineImage.rectTransform.localEulerAngles = new Vector3(0, 0, angle);
    }
}