Движение UI за GameObject

Есть ли какой то элегантный способ перемещать ui панель за объектом на сцене при условии что рендер мод канваса == Screen space - Overlay?

Я пока что делаю так:

private void Update()
{
   rect.position = Camera.main.WorldToScreenPoint(target.transform.position) + new Vector(0, 3, 0);
}

Где rect это RectTransform. Но кажется мне это костыль в апдейте.


Ответы (1 шт):

Автор решения: Yaroslav

Тут самое странное это каждый раз искать main камеру и обращаться к transform у GameObject который не используется.

Ты пользуешься RectTransform как обычным Transform, при сложной иерархии position в ui косячет. ScreenPoint это координата на дисплее, а не на Canvas, в твоем случае размер соответствует, на устройстве все легко подйдет нахер. Если объект будет дочерним тому, который не растянут до краев сломается сразу.

Кроме того new Vector(0, 3, 0), магическое число, значение которого нельзя изменить и почему оно такое знает только автор, не вынесенное как константа или поле. Тут ясно что это offset, не понятно только почему сдвиг не внутри скобок, а еще непонятней почему просто указать не сам объект как target, а пустой GameObject внутри него который выполняет функцию маркера позиции для ui и редактируется прямо в редакторе, причем для каждого типа персонажа под его рост. Вписывать offset как поле и уж темболее хардкодить как ты, вот уж где костыльные костыли.

public class UIFollowTarget : MonoBehaviour
{
    private RectTransform _transform;
    private RectTransform _parent;
    private Camera _camera;
    [SerializeField] private Transform _target;
    
    private void Start ()
    {
        _transform = transform as RectTransform;
        _parent = transform.parent as RectTransform;
        _camera = Camera.main;
    }

    public void SetTarget (Transform target)
    {
        _target = target;
    }

    private void Update ()
    {
        Vector3 screenPoint = _camera.WorldToScreenPoint(_target.position);
        RectTransformUtility.ScreenPointToLocalPointInRectangle(_parent, screenPoint, _camera, out Vector2 point);
        _transform.anchoredPosition = point;
    }
}
→ Ссылка