Почему разновидности и сколько их?


Часто сталкиваюсь с тем, что люди просто не понимают как подвинуть объект в UI на какое то значение, и удивляются что результат зачастую непредсказуем. Или допустим как получить правильные координаты объекта в UI. Если мы через дебагер выведем обычную позицию объекта(position), то она будет сильно отличаться от той что мы видим в инспекторе у UI элемента, так что же мы там видим и как это работает? В итоге перебираются 100500 решений с форумов пока какое либо не подойдет. Хочу придать подобным процессам осмысленное движение.

Суть подвоха заключается в следующем — у обычного Transform есть потомок RectTransform который и отвечает за положение и многие вещи связанные с размером, скейлом и тд — элемента UI. И благодаря ему мы можем получить следующие варианты координат.

  1. position
  2. localPosition
  3. anchoredPosition (есть еще anchoredPosition3D, но его не будем рассматривать отдельно, а будем считать что это подвид test.anchoredPosition



Обычная позиция


Обычная позиция не относится к системе координат UI от слова вообще. Это некие общие координаты объекта во всём мире юнити, и в мире некое представление позиции объекта которое не связано с интерфейсом.Eсли вы захотите сдвинуть объект на его ширину, это не сработает, так как у канваса координаты в пикселях относительно экрана. А в глобальных координатах это не пиксели. Поэтому объект сместится в мире допустим на 200 единиц измерения мира, а не на 200 пикселей, и просто улетит в неведомые дали. Но это можно разумно использовать. Позже расскажу как.

Якорная позиция (anchoredPosition)


То что мы видим в инспекторе — и есть оно.



В юнити можно выставлять якорные точки, это некая точка относительно которой будет позиционироваться UI элемент, в том числе при изменениях размера/пропорций родительского объекта.



Вот тут видно что мы поменяли размер родительского объекта и пропорции, наш объект придерживается центра родительского объекта, и его координаты не изменились, хотя на экране он уже не на том месте что раньше.

Якорная позиция — координаты объекта относительно якоря. Выставим якорь в левый верхний угол и увидим что координаты изменились.



Если вы хотите сместить объект на его ширину, то надо менять anchoredPosition или localPosition. Локальная позиция для UI элементов тоже вычисляется в пикселях, но по другому. Поэтому если вам нужно манипулировать двумя UI элементами относительно друг друга. То лучше использовать локальную позицию. Почему же?

Локальная позиция (localPosition)


Итак, что же такое локальная позиция:



Это система координат, когда в центре родительского объекта находится 0. Правый верхний угол это положительная ширина ректа делённая пополам. Левый верхний отрицательное значение ширины попалам. То есть если ширина ректа 800 пикселей, то посередине x =0, в правом верхнем 400, в левом верхнем -400. Поэтому если вам нужно без учёта якорей посчитать координаты — лучше использовать локальные позиции. При условии что у них общий предок/рект. К слову, якоря можно использовать не только как конкретную точку на родительском объекте, но и как пропорции относительно родительского объекта. Во втором случае anchoredPosition будет возвращать localPosition.

Для чего можно использовать обычный position для UI элементов? Скажем так, в рамках глобальных координат, если одному объекту назначить координаты второго, то они будут находится в одной точке, безотносительно своих якорей или локальных позиций, иногда это удобно — когда элементы находятся на разных канвасах/в разных панелях и системы координат локальные/якорные не совпадают.

Вывод/итог


  1. В инспекторе у UI элементов показываются anchoredPosition или пропорции относительно родительского объекта. AnchoredPosition считается в зависимости от положения якоря
  2. localPosition позволяет получить общие координаты относительно родителя, без привязки к якорям.
  3. position — это глобальня позиция элемента в пространстве сцены, не привязана к UI.


Надеюсь, кому-то поможет :-)